数据类型和文件格式
基本数据类型
数据类型 | 长度 | 例子 |
---|---|---|
TINYINT | 1byte有符号整数 | 20 |
SMALINT | 2byte有符号整数 | 20 |
INT | 4byte有符号整数 | 20 |
BIGINT | 8byte有符号整数 | 20 |
BOOLEAN | bool类型,true或false | TRUE |
FLOAT | 单精度浮点数 | 2.14159 |
double | 双精度浮点数 | 2.14159 |
STRING | 字符序列,可以指定字符集,可以使用单引号或者双引号 | “now is the time” |
TIMESTAMP() | 整数,浮点数或者字符串 | 1323882394,1323882394.1234,“2012-02-03 12:34:56.123456789”(JDBC所兼容的java.sql.TimeStamp时间格式) |
BINARY | 字节数组 | 请看后面的讨论 |
新增的数据类型TIMESTAMP的值可以是整数,也就是距离新纪元时间(1970年1月1日 午夜12点)的秒数,也可以使浮点数,既距离新纪元时间的秒数,精确纳秒(小数点后保留9位),还可以是字符串,既JDBC所约定的时间字符串格式,格式为"YYYY-MM-DD hh:mm:ss:fffffffff"
Hive 本身提供了不同时区互相转换的内置函数,也就是to_utc_timestamp函数和from_utc_timestamp函数(详情请看第13章的内容)
如果用户在查询中将一个float类型的列与一个double类型的列对比或者将一种整型类型的值和另一种整形类别的值作比较,那么结果将会怎样呢?Hive 会隐式的将类型转换为两个整形类型中值比较大的那个类型,也就是会将FLOAT类型转化为double类型,而且如有必要,也会将任意的整形类型转化为Double类型,因此实施上是同类型之间的比较。
如果用户希望将一个字符串类型的列转化为数值呢?这种情况下用户可以显式地将一种数据类型转化为其他一种数据类型
例如s是一个字符串类型列,其值为数值 cast(s AS INT)
AS INT是关键字使用小写也可以
集合数据类型
数据类型 | 描述 | 字面语法实例 |
---|---|---|
STRUCT | 和c语言中的struct或者对象类似。都可以通过"点"符号访问元素的内容。例如,如果某个列的数据类型是STRUCT{first STRING,last STRING }那么第一个元素可以用过z字段名.first来引用 | struct{“john”,“doe”} |
MAP | MAP是一组键值对元组集合,使用数字表示法(例如[‘key’]可以访问元素。;例如某个列的数据类型是MAP 其中键->值对是’first’->‘john’和’last’->'doe’那么可以通过字段名[‘last’]获取最后一个元素 | map(“first”,‘john’,‘last’,‘doe’) |
ARRAY | 数组是一组具有相同类型和名称的变量的集合,这些变量称为数组的元素,每个数组元素都有一个编号(索引)从0开始。例如数组值为[‘john’,‘doe’]那么第二个元素可以通过数组名[1]来获得第二个元素 | ARRAY(‘john’,‘doe’) |
这些数据格式在一些传统关系型数据库中并不支持,因为会增大数据冗余的风险进而消耗不必要的磁盘空间。那为什么在Hive中支持呢?在大数据系统中,实现这些格式可以提供更高吞吐量的数据。当处理的数据的数量级是T或者P时,以最少的"头部寻址"从磁盘上扫描速度是非常有必要的,通过数据集封装的话可以减少寻址次数来提升查询速度。
以上的话用人话说就是这些数据类型可能会造成冗余,但是实现这些数据格式,不用像关系型数据库那样去查找多个表,可以减少寻址次数,提升查询效率。
create table employees(
name STRING,
salary FLOAT,
subordinates ARRAY<STRING>,
deductions MAP<STRING,FLOAT>,
address STRUCT<street:STRING,city:STRING,state:STRING,zip:INT>
);
ARRAY表示ARRAY中的每个元素都是STRING类型
MAP<STRING,FLOAT>表示map中的每个键值对都是STRING->FLOAT类型的
STRUCTstreet:STRING,city:STRING,state:STRING,zip:INTstruct可以混合不同的类型,但是struct一旦声明好格式,区位置就不能改变了。
文本文件数据编码
分隔符 | 描述 |
---|---|
\n | 对于文本文件来说,每一行都是一条记录,因此换行符用于分割记录 |
^A | 用于分割字段(列),八进制的\001 |
^B | 用于分割ARRAY或者STRUCT中的元素,或用于MAP中键值对之间的分割,八进制\002 |
^C | 用于map中键与值之间的分割 八进制的\003表示 |
这些都是默认的分隔符,我们可以选择其他的分隔符
create table employees(
name STRING,
salary FLOAT,
subordinates ARRAY<STRING>,
deductions MAP<STRING,FLOAT>,
address STRUCT<street:STRING,city:STRING,state:STRING,zip:INT>
)
row format delimited
fields terminated by '\t'
collection items terminated by ','
map keys terminated by ':';
读时模式
传统的数据库是写时模式,既在数据写入是对模式进行检查。
hive对底层存储并没有这样的控制,hive不会再数据加载时进行验证么事在查询时进行验证,也就是读时模式。
那么如果模式和文件内容变不匹配将会怎么样?
hive对此做的非常好,因为其可以读取这些数据,如果每行中记录中的字段格式少于对应的模式中定义的字段个数的话,那么用户将会看到查询结果中有很多的null值。如果某些字段是树脂芯过得,但是hive在读取时发现是字符串的话,那么对于那些字段将会返回null值,除此之外hive将尽可能将各种错误恢复过来。