Hive_2. 数据类型

本文介绍了如何在Hive中使用复合数据类型,包括ARRAY、STRUCT和MAP。通过创建表、加载数据、查询数据,展示了如何访问ARRAY的元素、STRUCT的字段以及MAP的键值。还探讨了Hive数据类型的分隔符和转换,并提供了示例查询。

1. Hive 的数据类型

以下数据类型是根据最新的 Hive 0.14.0 版本进行总结。目前 Hive 支持14种基本数据类型 和 5种复杂数据类型:
1.1 基本数据类型:

数据类型    

Description

Example

TINYINT

1个字节(8位)有符号整数( 从-128 到 127), 后缀 Y 用来表示小范围的数字

10Y

SMALLINT

2字节(16位)有符号整数(从-32,768 到 32,767) , 后缀S用来表示一个egular descriptive number

10S

INT

4字节(32位)有符号整数(从-2,147,483,648 到  2,147,483,647)

10

BIGINT

8字节(64位)有符号整数(从-9,223,372,036,854,775,808 到 9,223,372,036,854,775,807),后缀为 L

100L

FLOAT

4字节(32位)单精度浮点数,范围在1.40129846432481707e-45 to 3.40282346638528860e+38 (正负值),暂时还不支持科学计数法。用它进行存储会非常接近数字值

1.2345679

DOUBLE

8字节(64位)双精度浮点数,范围在(4.94065645841246544e-324d 到 1.79769313486231570e+308d]正负值]。暂时还不支持科学计数法,用它来存储会非常接近数字值[numeric values]

1.2345678901234567

DECIMAL
十进制

从 Hive 0.11.0 版本开始引入的支持38位的硬编码。Hive 0.13.0版本推出用户自定义的精确度和规模。
它的范围在1039 - 1 to 1 - 1038之间,DECIMAL数据类型存储数据的精确值,它的默认定义格式是decimal(10,0).

DECIMAL (3,2) for 3.14

BINARY

从 Hive 0.80 版本开始引入,它只支持与STRING类型的转换,反之亦然。

1011

BOOLEAN

TRUE or FALSE

TRUE

STRING

它使用单引号(')或者双引号(")来表达包含的字符串。Hive 使用 C 语言格式的字符串,最大溢出大小在 2G左右。

'Books' or "Books"

CHAR

该类型从Hive 0.13.0以后可用,在 Hive 0.14 版本以后,可以在UDF中使用过该类型。它的最大长度是255

'US' or "US"

VARCHAR

从 Hive 0.12.0开始便支持该类型。从 Hive 0.14.0以后在 UDF 中可以使用该类型。它最大长度是65355。如果一个 STRING 类型值转换为 VARCHAR 的时超出指定长度,字符串将会被截取。 

'Books' or "Books"

DATE

从 Hive 0.12版本以后开始支持该类型。用来指定年,月,日。格式是 YYYY-MM-DD。它的范围从0000-01-01 to 9999-12-31

'2013-01-01'

TIMESTAMP

从Hive 0.8.0开始便支持该类型,它用来描述指定的年,月,日,时,分,秒,毫秒。格式是YYYY-MM-DD HH:MM:SS[.fff...]

'2013-01-01 12:00:01.345'


2. 复杂数据类型:
Hive 有3个主要的复杂数据类型: ARRAYMAP, 和 STRUCT。这些数据类型是建立在基本数据类型基础之上。STRUCT是一个 Record 类型,允许包含任意类型的字段。复杂数据类型允许嵌套类型:
复杂数据类型

描述

语法示例    

ARRAY

数组是一组具有相同类型和名称的有序变量的集合。这些变量成为数组的元素,每个数组元素有一个编号,而且从0开始。例如:fruit[0]='apple'

['apple','orange','mango']

MAP

一组无序的键/值对。键的类型必须是原子的,值可以是任何类型,同一个映射的键的类型必须相同,值得类型也必须相同
Map是一组无序的键值对元组的集合,使用数组表示法可以访问元素。例如,如果某个列的数据类型是 Map,其中 Key->value paris 对应的是'first'->'John' 和 'last'->'Doe'. 那么可以通过字段名 ['last'] 获取最后一个元素: fruit['last']='Doe'.

map('first', 'John', 'last', 'Doe')

STRUCT

一组命名的字段。字段类型可以不同。和 C 语言中的 struct 或者"对象“类似,都可以通过"点"分隔符访问元素内容。例如{val1, val2, val3, ....},默认情况下, STRUCT 字段名可以是col1,col2,...你可以通过structs_name.column_name 来访问具体的值: fruit.col1=1.

{1, "apple"}

NAMED STRUCT

这是用户为任意数据类型字段定义的结构,比如(name1, val1, name2, val2, ...).你可以通过structs_name.column_name来访问数据:fruit.apple="gala".

{"apple":"gala","weight kg":1}

UNION

从 Hive 0.7.0开始可用。它用来表达任意一种指定的数据类型,但是不怎么常用

{2:["apple","orange"]}

Note

对 MAP类型来说键和值是一致的。但是,STRUCT更加复杂,STRUCT类型就像是一张表,而 MAP 类型则像包含自定义索引的数组。

接下来,我们将通过一些具体的练习来看看如何使用个 Hive 的类型。CREATELOAD, 和 SELECT语句会在稍后进行介绍:

1. 准备数据 :
-bash-4.1$ vi employee.txt
Michael|Montreal,Toronto|Male,30|DB:80|Product:Developer^DLead
Will|Montreal|Male,35|Perl:85|Product:Lead,Test:Lead
Shelley|New York|Female,27|Python:80|Test:Lead,COE:Architect
Lucy|Vancouver|Female,57|Sales:89,HR:94|Sales:Lead
2. 提供正确的HiveServer2 的主机名, 端口名,数据库名, 用户名,密码来登陆到 Beeline:
-bash-4.1$ beeline
beeline> !connect jdbc:hive2://localhost:10000/default
scan complete in 20ms Connecting to jdbc:hive2://localhost:10000/default
Enter username for jdbc:hive2://localhost:10000/default:dayongd Enter password for jdbc:hive2://localhost:10000/default:
3. 使用复合数据类型 ARRAY, MAP, and STRUCT  来创建一张表 :
jdbc:hive2://> CREATE TABLE employee
. . . . . . .> (
. . . . . . .> name string,
. . . . . . .> work_place ARRAY<string>,
. . . . . . .> sex_age STRUCT<sex:string,age:int>,
. . . . . . .> skills_score MAP<string,int>,
. . . . . . .> depart_title MAP<string,ARRAY<string>>
. . . . . . .> )
. . . . . . .> ROW FORMAT DELIMITED
. . . . . . .> FIELDS TERMINATED BY '|'
. . . . . . .> COLLECTION ITEMS TERMINATED BY ','
. . . . . . .> MAP KEYS TERMINATED BY ':';
No rows affected (0.149 seconds)
4. 检查表的创建:
jdbc:hive2://>!table employee
+---------+------------+------------+--------------+---------+
|TABLE_CAT|TABLE_SCHEMA| TABLE_NAME | TABLE_TYPE | REMARKS |
+---------+------------+------------+--------------+---------+
| |default | employee | MANAGED_TABLE| |
+---------+------------+------------+--------------+---------+

jdbc:hive2://>!column employee
+--------------+-------------+---------------+---------------+
| TABLE_SCHEM | TABLE_NAME | COLUMN_NAME | TYPE_NAME |
+--------------+-------------+---------------+---------------+
| default | employee | name | STRING |
| default | employee | work_place | array<string> |
| default | employee | sex_age | struct<sex:string,age:int>|
| default | employee | skills_score | map<string,int>|
| default | employee | depart_title | map<string,array<string>> |
+--------------+-------------+---------------+---------------+
5. 将数据加载到表中 :
jdbc:hive2://>LOAD DATA LOCAL INPATH '/home/hadoop/employee.txt' 
. . . . . . .>OVERWRITE INTO TABLE employee;
No rows affected (1.023 seconds)
6. 查询表中的 Rows: 
jdbc:hive2://> SELECT * FROM employee;
+-------+-------------------+------------+-----------------+------------------------------+
| name | work_place | sex_age | skills_score | depart_title |
+-------+-------------------+------------+-----------------+------------------------------+
|Michael|[Montreal, Toronto]|[Male, 30] |{DB=80} |{Product=[Developer, Lead]} |
|Will |[Montreal] |[Male, 35] |{Perl=85} |{Test=[Lead], Product=[Lead]} |
|Shelley|[New York] |[Female, 27]|{Python=80} |{Test=[Lead], COE=[Architect]}|
|Lucy |[Vancouver] |[Female, 57]|{Sales=89, HR=94}|{Sales=[Lead]} |
+-------+-------------------+------------+-----------------+------------------------------+
4 rows selected (0.677 seconds)
6.1 ARRAY - 查询表中的整个数组和数组的每个列:
jdbc:hive2://> SELECT work_place FROM employee;
+----------------------+
| work_place |
+----------------------+
| [Montreal, Toronto] |
| [Montreal] |
| [New York] |
| [Vancouver] |
+----------------------+
4 rows selected (27.231 seconds)
jdbc:hive2://> SELECT work_place[0] AS col_1,
. . . . . . .> work_place[1] AS col_2, work_place[2] AS col_3
. . . . . . .> FROM employee;
+------------+----------+--------+
| col_1 | col_2 | col_3 |
+------------+----------+--------+
| Montreal | Toronto | |
| Montreal | | |
| New York | | |
| Vancouver | | |
+------------+----------+--------+
4 rows selected (24.689 seconds)
6.2 STRUCT -- 查询表中的整个 STRUCT 和 每个 STURCT 的列:
jdbc:hive2://> SELECT sex_age FROM employee;
+---------------+
| sex_age |
+---------------+
| [Male, 30] |
| [Male, 35] |
| [Female, 27] |
| [Female, 57] |
+---------------+
4 rows selected (28.91 seconds)
jdbc:hive2://> SELECT sex_age.sex, sex_age.age FROM employee;
+---------+------+
| sex | age |
+---------+------+
| Male | 30 |
| Male | 35 |
| Female | 27 |
| Female | 57 |
+---------+------+
4 rows selected (26.663 seconds)
6.3 MAP -- 查询表中的 Map 类型字段 :
jdbc:hive2://> SELECT skills_score FROM employee;
+--------------------+
| skills_score |
+--------------------+
| {DB=80} |
| {Perl=85} |
| {Python=80} |
| {Sales=89, HR=94} |
+--------------------+
4 rows selected (32.659 seconds)
jdbc:hive2://> SELECT name, skills_score['DB'] AS DB,
. . . . . . .> skills_score['Perl'] AS Perl,
. . . . . . .> skills_score['Python'] AS Python,
. . . . . . .> skills_score['Sales'] as Sales,
. . . . . . .> skills_score['HR'] as HR
. . . . . . .> FROM employee;
+----------+-----+-------+---------+--------+-----+
| name | db | perl | python | sales | hr |
+----------+-----+-------+---------+--------+-----+
| Michael | 80 | | | | |
| Will | | 85 | | | |
| Shelley | | | 80 | | |
| Lucy | | | | 89 | 94 |
+----------+-----+-------+---------+--------+-----+
4 rows selected (24.669 seconds)

Note:你应该注意到,在Hive 查询显示的字段名都是小写字母

7. 查询表中的复合类型:
jdbc:hive2://> SELECT depart_title FROM employee;
+---------------------------------+
| depart_title |
+---------------------------------+
| {Product=[Developer, Lead]} |
| {Test=[Lead], Product=[Lead]} |
| {Test=[Lead], COE=[Architect]} |
| {Sales=[Lead]} |
+---------------------------------+
4 rows selected (30.583 seconds)
jdbc:hive2://> SELECT name,
. . . . . . .> depart_title['Product'] AS Product,
. . . . . . .> depart_title['Test'] AS Test,
. . . . . . .> depart_title['COE'] AS COE,
. . . . . . .> depart_title['Sales'] AS Sales
. . . . . . .> FROM employee;
+--------+--------------------+---------+-------------+------+
| name | product | test | coe |sales |
+--------+--------------------+---------+-------------+------+
| Michael| [Developer, Lead] | | | |
| Will | [Lead] | [Lead] | | |
| Shelley| | [Lead] | [Architect] | |
| Lucy | | | |[Lead]|
+--------+--------------------+---------+-------------+------+
4 rows selected (26.641 seconds) -->查询每个人所对应的部门和 Title

jdbc:hive2://> SELECT name,
. . . . . . .> depart_title['Product'][0] AS product_col0,
. . . . . . .> depart_title['Test'][0] AS test_col0
. . . . . . .> FROM employee;
+----------+---------------+------------+
| name | product_col0 | test_col0 |
+----------+---------------+------------+
| Michael | Developer | |
| Will | Lead | Lead |
| Shelley | | Lead |
| Lucy | | |
+----------+---------------+------------+
4 rows selected (26.659 seconds)

2. Hive 输出文件分隔符

Hive 0.11.0 版本新引进了一个特性:用户将 Hive 查询结果输出到文件中的时候,可以指定列的分隔符,而之前版本中无法指定列之间的分隔符,给我们后续的分析带来了读写的不便。
Hive 中默认分隔符有:

  • Row delimiter :可以使用Ctrl + A或者 ^A(创建表的时候使用 \001 ) 
  • Collection item delimiter :可以使用 Ctrl + B or ^B (\002)  
  • Map key delimiter :可以使用 Ctrl + C or ^C (\003

在创建表的时候,指定的分隔符只能显示在文本文件中。使用文本编辑器查看的时候,我们是看不到^A的,而是一个奇怪的符号。
这依然是 Hive 目前的一个限制,详细可以参考 Apache Jira Hive-365 :(https://issues.apache.org/jira/browse/HIVE-365)
示例如下:

Hive 0.11.0 之前版本:保存的文件列之间用^A(\x01)来分割
 Hive 0.11.0 版本 及以后:使用空格‘\t’来进行分割
hive> insert overwrite local directory '/home/wyp/Documents/result
hive> select * from test;

hive> insert overwrite local directory '/home/wyp/Documents/result'
hive> row format delimited
hive> fields terminated by '\t'
hive> select * from test;

1    196^A242^A3
2    186^A302^A3
3    22^A377^A1
4    244^A51^A2
1    196 242 3
2    186 302 3
3    22  377 1
4    244 51  2

对应嵌套类型,例如之前表中的depart_title 字段,嵌套的级别决定了分隔符。拿含有ARRAYARRAY作为例子来说, ARRAY外部的分隔符是Ctrl + B (\002)字符,跟预期一样。但是ARRAY内部的分隔符却是列表中下一个分隔符Ctrl + C (\003) 。在含有 ARRAYMAP 中,Map 的分隔符是 \003,Array 的分隔符是Ctrl + D or ^D (\004)

hive> insert overwrite local directory './test-04'
hive> row format delimited
hive> FIELDS TERMINATED BY '\t'
hive> COLLECTION ITEMS TERMINATED BY ','
hive> MAP KEYS TERMINATED BY ':'
hive> select * from src;

如果在Hive 中指定多个字符作为分隔符:http://my.oschina.net/u/1167806/blog/200808

3. Hive 数据类型转换

同Java语言一样,Hive也包括隐式转换(implicit conversions)和显式转换(explicitly conversions)。
  Hive在需要的时候将会对numeric类型的数据进行隐式转换。比如我们对两个不同数据类型的数字进行比较,假如一个数据类型是INT型,另一个是SMALLINT类型,那么SMALLINT类型的数据将会被隐式转换地转换为INT类型,这个到底和Java中的一样;但是我们不能隐式地将一个INT类型的数据转换成SMALLINT或TINYINT类型的数据,这将会返回错误,除非你使用了CAST操作。

  任何整数类型都可以隐式地转换成一个范围更大的类型。TINYINT,SMALLINT,INT,BIGINT,FLOAT和STRING都可以隐式地转换成DOUBLE;是的你没看出,STRING也可以隐式地转换成DOUBLE!但是你要记住,BOOLEAN类型不能转换为其他任何数据类型!

下标列出了Hive内置的数据类型之间是否可以进行隐式的转换操作:

  bl tinyint si int bigint float double dm string vc ts date ba
boolean true false false false false false false false false false false false false
tinyint false true true true true true true true true true false false false
smallint false false true true true true true true true true false false false
int false false false true true true true true true true false false false
bigint false false false false true true true true true true false false false
float false false false false false true true true true true false false false
double false false false false false false true true true true false false false
decimal false false false false false false false true true true false false false
string false false false false false false true true true true false false false
varchar false false false false false false true true true true false false false
ts false false false false false false false false true true true false false
date false false false false false false false false true true false true false
binary false false false false false false false false false false false false true
   注:由于表格比较大,这里对一些比较长的字符串进行缩写,ts是timestamp的缩写,bl是boolean的缩写,sl是smallint的缩写,dm是decimal的缩写,vc是varchar的缩写,ba是binary的缩写。

我们可以用CAST来显式的将一个类型的数据转换成另一个数据类型。如何使用?CAST的语法为cast(value AS TYPE)。举个例子:假如我们一个员工表employees,其中有name、salary等字段;salary是字符串类型的。有如下的查询: 

      SELECT name, salary FROM employees
      WHERE cast(salary AS FLOAT) < 100000.0;

这样salary将会显示的转换成float。如果salary是不能转换成float,这时候cast将会返回NULL!

  对cast有一下几点需要说明的:
  (1)、如果将浮点型的数据转换成int类型的,内部操作是通过round()或者floor()函数来实现的,而不是通过cast实现!
  (2)、对于BINARY类型的数据,只能将BINARY类型的数据转换成STRING类型。如果你确信BINARY类型数据是一个数字类型(a number),这时候你可以利用嵌套的cast操作,比如a是一个BINARY,且它是一个数字类型,那么你可以用下面的查询:
         SELECT (cast(cast(a as string) as double)) from src; 
我们也可以将一个String类型的数据转换成BINARY类型。
    (3)、对于Date类型的数据,只能在Date、Timestamp以及String之间进行转换。下表将进行详细的说明:

有效的转换 结果
cast(date as date) 返回date类型
cast(timestamp as date) timestamp中的年/月/日的值是依赖与当地的时区,结果返回date类型
cast(string as date) 如果string是YYYY-MM-DD格式的,则相应的年/月/日的date类型的数据将会返回;
但如果string不是YYYY-MM-DD格式的,结果则会返回NULL。
cast(date as timestamp) 基于当地的时区,生成一个对应date的年/月/日的时间戳值
cast(date as string) date所代表的年/月/日时间将会转换成YYYY-MM-DD的字符串。
更多细节请参考: https://cwiki.apache.org/confluence/display/Hive/LanguageManual+Types .


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值