Hive 存储格式

摘录自《Hadoop 权威指南》

Hive 从两个维度对表的存储进行管理,分别是行格式(row format)和文件格式(file format)。行格式指行和一行中的字段如何存储。按照 Hive 的术语,行格式的定义由 SerDe 定义。SerDe 是“序列化和反序列化工具”(Serializer-Deserialize)的合成词。

当作为反序列化工具进行使用时,也就是查询表时,SerDe 将把文件中字节形式的数据行反序列化为 Hive 内部操作数据行时使用的对象形式。使用序列化工具时,也就是执行 INSERT 或 CTAS(CREATE TABLE … AS SELECT)时,表的 SerDe 会把 Hive 的数据行内部表示形式序列化成字节形式并写到输出文件中。

文件格式指一行字段容器的格式,最简单的格式是纯文本文件,但是也可以使用面向行的和面向列的二进制格式。

1. 默认存储格式:分割的文本

如果在创建表没有用 ROW FORMAT 或 STORED AS 子句,那么 Hive 所使用的默认格式是分隔的文本,每行(line)存储一个数据行(row)。

默认的行内分隔符不是制表符,而是 ASCII 控制码集合中的 Control-A(它的 ASCII 码为 1)。选择 Control-A(在文档中有时记作 ^A )作为分隔符是因为和制表符相比,它出现在字段文本中的可能性比较小。在 Hive 中无法对分隔符进行转义,因此,挑选一个不会在数据字段中用到的字符作为分隔符非常重要。

集合类元素的默认分隔符为字符 Control-B。它用于分隔 ARRAY 或 STRUCT 或 MAP 的键-值对中的元素。默认的映射键(map key)分隔符为字符 Control-C。它用于分隔 MAP 的键和值。表中各行之间用换行符分隔。

前面对分隔符的描述,对于一般情况下的平面数据结构——即只包含原子数据类型的复杂数据类型——都是没问题的。但是,对于嵌套数据类型,这还不够。事实上,嵌套的层次(level)决定了使用哪种分隔符。
例如,对于数组的数组,外层数据的分隔符如前所述是 Control-B 字符,但内层数据则使用分隔符列表中的下一项(Control-C 字符)作为分隔符。如果不确定 Hive 使用哪个字符作为某个嵌套结构的分隔符,可以运行以下命令:

CREATE TABLE nested
AS
SELECT array(array(1, 2), array(3, 4))
FROM dummy;

然后再使用 hexdump 或类似的命令查看输出文件的分隔符。
实际上,Hive 支持 8 级分隔符,分别对应于 ASCII 编码的 1,2,……,8。但是只能重载其中的前三个。

因此,以下语句:

CREATE TABLE ...;

等价于下面显示说明的语句:’

CREATE TABLE ...
ROW FORMAT DELIMITED
 FIELDS TERMINATED BY '\001'
 COLLECTION ITEMS TERMINATED BY '\002'
 MAP KEYS TERMINATED BY '\003'
 LINES TERMINATED BY '\n'
STORED AS TEXTFILE; 

注意,可以使用八进制形式表示分隔符,例如,001 表示 Control-A。

Hive 在内部使用一个名为 LazySimpleSerDe 的 SerDe 来处理这种分隔符格式以及面向行的 MapReduce 文本输入和输出格式。这里使用前缀“lazy”的原因是这个 SerDe 对字段的反序列化是延迟处理的,只有在访问字段时才会反序列化。但是,由于文本以冗余的形式进行存放,所以这种存储格式并不紧凑。比如,一个布尔值事实上是以文本字符串 true 或 false 的形式存放的。

这种简单的格式有很多好处,例如,使用其它工具(包括 MapReduce 程序或 Streaming)来处理这样的格式非常容易。但是还可以选择一些更紧凑和高效的二进制 SerDe。

2. 二进制存储格式:顺序文件、Avro 数据文件、Parquet 文件、RCFile 与 ORCFile

二进制格式的使用方法非常简单,只需要通过 CREATE TABLE 语句中的 STORED AS 子句做相应声明。这里不需要指定 ROW FORMAT,因为其格式由底层的二进制文件格式来控制。

二进制格式可分为两大类:面向行的格式和面向列的格式。一般来说,

  • 面向列的存储格式对于那些只访问表中一小部分列的查询比较有效;
  • 相反,面向行的存储格式适合同时处理一行中很多列的情况;

Hive 本身支持两种面向行的格式:Avro 数据文件和顺序文件,它们都是通用的可分割、可压缩的格式。另外,Avro 还支持模式演化以及多种编程语言的绑定。在 Hive 0.14.0 之后版本中,使用下述语句可以将表存储为 Avro 格式:

SET hive.exec.compress.output=true;
SET avro.output.codec=snappy;
CREATE TABLE ... STORED AS AVRO;

请注意,通过设置相应的属性即可支持表压缩。

类似地,Hive 利用 CREATE TABLE 语句中的 STORED AS SEQUNCEFILE 子句声明,将顺序文件作为存储格式。Hadoop 压缩

Hive 本身可支持的面向列的格式包括:Parquet、RECFile 和 ORCFile。下面这个示例使用 CREATE TABLE … AS SELECT 语句来创建一个表的 parquet 格式的复本。

CREATE TABLE users_parquet STORED AS PARQUET
AS
SELECT * FROM users;
3. 使用定制的 SerDe:RegexSerDe
CREATE TABLE table_name
...
ROW FORMAT SERDE 'org.apache.hadoop.hive.contrib.serde2.RegexSerDe'
WIHT SERDEPROPERTIES ("input.regex" = "(\\d{6})(\\d{5}(.{29})).*")
;

SerDe 可以用 WITH SERDEPROPERTIES 子句来设置额外的属性。上面设置 RegexSerDe 特有的 input.regex 属性。

4. 存储句柄

存储句柄(Storage handler)用于 Hive 自身无法访问的存储系统,比如 HBase。存储句柄使用 STORED BY 子句指定。它代替了 ROW FORMAT 和 STORED AS 子句。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值