Hive支持RDBMS中的大多数数据类型,同时也支持RDBMS中很少支持的3中集合数据类型。
一、基本数据类型
1. Integers 整数型
TINYINT—1 byte integer
SMALLINT—2 byte integer
INT—4 byte integer
BIGINT—8 byte integer
以上这些都是有符号的整型。
2. Boolean type 布尔型
BOOLEAN—TRUE/FALSE
3. Floating point numbers 浮点型
FLOAT—single precision 单精度浮点
DOUBLE—Double precision 双精度浮点
4. Fixed point numbers 定点型
DECIMAL—a fixed point value of user defined scale and precision
5. String types 字符序列
STRING—sequence of characters in a specified character set
VARCHAR—sequence of characters in a specified character set with a maximum length
CHAR—sequence of characters in a specified character set with a defined length
7. Date and time types 时间类型
TIMESTAMP—a specific point in time, up to nanosecond precision
DATE—a date
8. Binary types 字节数组
BINARY—a sequence of bytes
为什么有的字符类型很特殊呢? 这是因为所有这些数据类型都是对Java中的接口的实现,比如string类型实现的和Java中的string,float中也是对Java中的float。
但是其他RDBMS通常也会提供限制最大长度的字符数组,而在Hive中却不会支持。因为处于性能优化的考虑,这些定长的记录容易进行索引、扫描等。而在Hive强调优化磁盘读写的性能对限制列的长度相对来说不是很重要。
在Hive0.8.0以后的timestamp、binary数据类型数据类型;timestamp指可以为整数,也就是距离Unix新纪元的秒数;也可以是浮点数,距离到纳秒(小数点后保留9位),也可以是字符串,即JDBC所约定的的字符串格式,比如:yyyy-mm-dd hh24:mi:ss.fffffffff。
binary类型和其他的RDBMS数据库中的varbinary很类似。不过它并不和blob数据类型并不同。因为binary列存储在记录中,而blob不同。
当用户查询用到不同的浮点列对比是,比如将float和double列进行对比或一个整数列和另一种整数列对比时,Hive会怎么样处理呢?遇到这种情况,Hive会隐式的将把数据类型转换为两个数据类型较大的那个处理,也就是将float转换成double。
二、集合数据类型
Hive 中的列支持使用 struct、map、array 集合数据类型,如下:
STRUCT列类型为struct{first STRING,last STRING} 如: struct('john','Doe')
MAP是一组键值对集合 字段名[last]获取值 如:map('first','Join','last','Doe')
ARRAY是具有相关同类型和名称的变量的集合['John','Doe'] 如:Array(['John','Doe'] )
大多数的关系型数据库并不支持这些集合数据类型,这有破坏标准数据格式的危险。通常在RDBMS中的处理方式大概用主外键关联。我们知道主外键关联的话在进行TB级以上的数据处理时会造成性能的极大消耗。但在大数据库架构中,这种设计却有助于提高数据吞吐量。
例如:
CREATE TABLE employees(
name STRING,
salary float,
subordinates array<string>,
deductions map<string,float>,
address struct<street:string,city:string,state:string,zip:int>
)
name --雇员名,salary --雇员薪水,subordinates --下属员工,deductions --五险一金,个税等,address --雇员的住址
很明显,一个雇员表详细信心存储在一张表中,在RDBMS中则可能存在某个字段的信息存储在另外一张表,通过主外键或查询条件进行连接后获取结果。这里可以通过一些集合数据类型进行处理了就。
三、文本文件的数据编码
我们知道,一个文本文件如果需要进行数据处理,就需要对其中的格式进行定义,我们最熟悉的应该是以逗号或制表符分隔的文本格式CSV、TSV,当然在Hive中,这些文本格式都是被支持的。
那么Hive中还会支持其他什么控制字符的文本格式呢?
\n 换行符是可以支持的,因为每一行都可以被认为是一条记录
^A(Ctrl+A) 分隔字段,在 CREATE TABLE 语句中可以使用八进制编码(\001)表示
^B 分隔 ARRAY 、MAP或者 STRUCT 中的元素,键值对之间的分隔,使用八进制编码(\002)表示
^C 用于 MAP 中键和值之间的分隔,使用八进制编码(\003)表示
比如将一个特定格式的文件插入到employees库中,文件打开后数据格式显示如下:
Shkodran Mustafi^A5000^ALaurent Koscielny^BRobert Holding^BHector Bellerin^AFederal^C.2^BState Taxes^C.05^BInsurance^C.1^A 1 Michigan Ave.^BChicago^BIL^B60600
我们可以针对此文件进行分解,让我们对格式更加清晰一些:
1、Shkodran Mustafi 对应 'name'字段,字段间用^A分割,所有在和salary字段之间的地方使用了^A。
2、5000对应’salary'字段,同样的用^A 隔断下一个字段。
3、Laurent Koscielny^BRobert Holding^BHector Bellerin 对应'subordinates'字段,针对array元素内的分割使用^B。
4、Federal^C.2^BState Taxes^C.05^BInsurance^C.1 对应‘deductions’字段,map元素内的分割使用^C。
5、1 Michigan Ave.^BChicago^BIL^B60600 对应‘address’字段,struct元素内的分割使用^B。
拆分后,是不是很清楚了呢?
也可以不使用这些默认的分隔符,而指定其他的分隔符,例如之前的表可以:
CREATE TABLE employees(
name STRING,
salary FLOAT,
subordinates ARRAY(STRING),
deductions MAP(STRING,FLOAT),
address STRUCT
)
ROW FORMAT DELIMITED--必须写在下面的子句之前(stored as 除外)
FILEDS TERMINATED BY '\001'--Hive 将使用 ^A 做为列分隔符
COLLECTION ITEMS TERMINATED BY '\002'--表明Hive 将使用 ^B 做为集合元素间分隔符
MAP KEYS TERMINATED BY '\003'--表明Hive 将使用 ^C 做为 MAP 的键值之间的分隔符
LINES TERMINATED BY '\n'--下面这两句表明不需要 ROW FORMAT DELIMITED 做关键字
STORED AS TEXTFILE;--此句很少被用到
另外,定义一个表是按照逗号来分隔的数据表可以这么来:
create table test_2(fistr float, second float, third float) row format delimited fileds terminated by ',';
虽然用户可以自定义一些分隔符,但是大多数子句还是使用默认分隔符的,只需要指定明确替换的分隔符即可。所以Hive可以容易的使用由很多ETL工具或其他程序产生的文件。
四、读时模式
当用户向数据库进行数据写入时,可以采用外部装载、update语句,或者查询写入。传统数据库时写时模式,什么意思呢,即只在数据写入时对模式进行检查。
Hive对底层存储没有一些控制手段,对于要查询的数据,有很多方式可以进行创建、修改或进行破坏。因此,hive不会在数据加载时才对模式进行验证,而在查询时就对其模式进行验证,这是读时模式。
如果模式和文件内容并不匹配,每行记录中的字段个数少于对应的模式中定义的字段个数的话,那么用户将会看到查询结果中有很多 null 值 ;如果某些字段是数值型的,但Hive 在读取的时候发现存在非数值型的字符串值的话,将返回 null 值。