Hive_2. 数据类型

来源:互联网 发布:世界上首例网络攻击 编辑:程序博客网 时间:2024/06/05 16:43

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内置的数据类型之间是否可以进行隐式的转换操作:

 bltinyintsiintbigintfloatdoubledmstringvctsdatebabooleantruefalsefalsefalsefalsefalsefalsefalsefalsefalsefalsefalsefalsetinyintfalsetruetruetruetruetruetruetruetruetruefalsefalsefalsesmallintfalsefalsetruetruetruetruetruetruetruetruefalsefalsefalseintfalsefalsefalsetruetruetruetruetruetruetruefalsefalsefalsebigintfalsefalsefalsefalsetruetruetruetruetruetruefalsefalsefalsefloatfalsefalsefalsefalsefalsetruetruetruetruetruefalsefalsefalsedoublefalsefalsefalsefalsefalsefalsetruetruetruetruefalsefalsefalsedecimalfalsefalsefalsefalsefalsefalsefalsetruetruetruefalsefalsefalsestringfalsefalsefalsefalsefalsefalsetruetruetruetruefalsefalsefalsevarcharfalsefalsefalsefalsefalsefalsetruetruetruetruefalsefalsefalsetsfalsefalsefalsefalsefalsefalsefalsefalsetruetruetruefalsefalsedatefalsefalsefalsefalsefalsefalsefalsefalsetruetruefalsetruefalsebinaryfalsefalsefalsefalsefalsefalsefalsefalsefalsefalsefalsefalsetrue
  注:由于表格比较大,这里对一些比较长的字符串进行缩写,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.


0 0
原创粉丝点击