第3章:数据类型和文件格式

基本数据类型

数据类型 长度 例子
TINYINT 1byte有符号整数 20
SMALLINT 2byte有符号整数 20
INT 4byte有符号整数 20
BIGINT 8byte有符号整数 20
BOOLEAN 布尔类型,true或者false TRUE
FLOAT 单精度浮点数 3.14159
DOUBLE 双精度浮点数 3.14159
STRING 字符序列。可以指定字符集。可以使用单引号或者双引号 ‘now is the time’,”for all good man”
TIMESTAMP 整数,浮点数或者字符串 1327882394(Unix新纪元秒)
1327882394.123456789(Unix新纪元秒并跟随纳秒数)
‘2012-02-03 12:34:56.123456789’ (JDBC所兼容的java.SQL.Timestamp时间格式)
BINARY 字节数组
这些数据类型完全是对java中的接口的实现,这些类型的具体行为细节和java中的对应的类型是完全一致的。

集合数据类型

数据类型 描述 字面语法实例
STRUCT 和对象类似,可以通过“点”符号访问元素内容。
例如如果某个列的数据类型是STRUCT{first STRING,last STRING},那么第一个元素可以通过 字段名.first 来引用
struct(‘John’,’Doe’)
MAP 一组键值对元组结合,使用数组表示法可以访问元素。
例如某个列的元素类型是MAP,其中键值对是’first’ -> ‘John’ 和 ‘last’ -> ‘Doe’,那么可以通过 字段名[‘last’] 获取最后一个元素
map(‘first’,’John’,’last’,’Doe’)
ARRAY 同java数组 Array(‘John’,’Doe’)
1
2
3
4
5
6
7
CREATE TABLE employees{
name STRING,
salary FLOAT,
subordinates ARRAY<STRING>,
deductions MAP<STRING,FLOAT>,
address STRUCT<street:STRING,city:STRING,state:STRING,zip:INT>
);
STRUCT可以混合多种不同的数据类型,但是STRUCT中一旦声明好结构,那么其位置就不可以再改变

文本文件数据编码

Hive中默认的记录和字段分隔符

分隔符 描述
\n 对于文本文件来说,每行都是一条记录,因此换行符可以分割记录
^A (Ctrl+A) 对于分隔字段(列)。
在CREATE TABLE语句中可以使用八进制编码\001表示
^B 用于分隔ARRAY或者STRUCT中的元素,或用于MAP中键值对之间的分隔。
在CREATE TABLE语句中可以使用八进制编码\002表示
^C 用于MAP中键和值之间的分隔。
在CREATE TABLE语句中使用八进制编码\003表示
John^A100000.0^AMary Smith^BTodd Jones^AFederal Taxes^C.2^BStateTaxes^C.05^BInsurance^C.1^A1 Michigan Ave.^BChicago^BIL^B60600

对应JSON:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
{
"name": "Jone Doe",
"salary": 100000.0,
"subordinates": ["Mary Smith", "Todd Jones"],
"deductions": {
"Federal Taxes": .2,
"State Taxes": .05,
"Insurance": .1
},
"address":{
"street":"1 Michigan Ave.",
"city": "Chicago",
"state": "IL",
"zip": 60600
}
}

用户可以不使用这些默认的分隔符而指定使用其他分隔符。

例如:

1
2
3
4
5
6
7
8
9
10
11
12
13
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 '\001'
COLLECTION ITEMS TERMINATED BY '\002'
MAP KEYS TERMINATED BY '\003'
LINES TERMINATED BY '\n'
STORED AS TEXTFILE;
- ROW FORMAT DELIMITED这组关键字必须要写在其他子句之(除了STORED AS ...)前
- 字符\001是^A的八进制数。FIELDS TERMINATED BY '\001'这个子句表明Hive将使用^A字符作为列分隔符
- 字符\002是^B的八进制数。COLLECTION ITEMS TERMINATED BY '\002'这个子句表明Hive将使用^B作为集合元素之间的分隔符
- 字符\003是^C的八进制数。MAP KEYS TERMINATED BY '\003'这个子句表明Hive将使用^C作为map的键和值之间的分隔符
- LINES TERMINATED BY '\n'和STORED AS TEXTFILE不需要ROW FORMAT DELIMITED
- LINES TERMINATED BY ...目前仅支持'\n'

读时模式

  • 传统数据库对于存储具有完全的控制力,是“写时模式”,即数据在写入数据库时对模式进行检查。

  • Hive对底层存储并没有这样的控制。Hive不会在数据加载时进行验证,而是在查询时进行,是“读时模式”。

    如果每行记录中的字段个数少于对应的模式中定义的字段个数的话,用户将会看到查询结果中有很多的null值,
    如果某些字段是数值型的,但是Hive在读取时发现存在非数值型的字符串值得话,那么对于那些字段将会返回null值。
    除此之外Hive极力尝试尽可能地将各种错误恢复过来。