Hive常见文件存储格式

  • 背景:列式存储和行式存储
    首先来看一下一张表的存储格式:

字段A

字段B

字段C

A1

B1

C1

A2

B2

C2

A3

B3

C3

A4

B4

C4

A5

B5

C5

行式存储



A1B1C1 A2B2C2 A3B3C3 A4B4C4 A5B5C5



列式存储



A1A2A3A4A5 B1B2B3B4B5 C1C2C3C4C5



优缺点比较:

行式存储

优点:

  • 相关的数据是保存在一起,比较符合面向对象的思维,因为一行数据就是一条记录
  • 这种存储格式比较方便进行INSERT/UPDATE操作

缺点:

 

  • 如果查询只涉及某几个列,它会把整行数据都读取出来,不能跳过不必要的列读取。当然数据比较少,一般没啥问题,如果数据量比较大就比较影响性能
  • 由于每一行中,列的数据类型不一致,导致不容易获得一个极高的压缩比,也就是空间利用率不高
  • 不是所有的列都适合作为索引

列式存储

优点:

  • 查询时,只有涉及到的列才会被查询,不会把所有列都查询出来,即可以跳过不必要的列查询
  • 高效的压缩率,不仅节省储存空间也节省计算内存和CPU
  • 任何列都可以作为索引

缺点:

  • INSERT/UPDATE很麻烦或者不方便
  • 不适合扫描小量的数据

 



hive文件存储格式包括以下几类:

  • TEXTFILE
  • SEQUENCEFILE
  • RCFIL
  • ORCFILE(0.11以后出现)
    其中TEXTFILE为默认格式,建表时不指定默认为这个格式,导入数据时会直接把数据文件拷贝到hdfs上不进行处理;
    SEQUENCEFILE,RCFILE,ORCFILE格式的表不能直接从本地文件导入数据,数据要先导入到textfile格式的表中, 然后再从表中用insert导入SequenceFile,RCFile,ORCFile表中。

首先创建一张source_table表,格式为textfile。



create table source_table(id int,name string, age int) row format delimited fields terminated by ',' stored as textfile;

load data local inpath '/root/hivedata/source_table.txt' into table source_table;
1,allen1,18
2,allen2,18
3,allen3,18
4,allen4,18
5,allen5,18
6,allen6,18
7,allen7,18
8,allen8,18
9,allen9,18
10,allen10,18



TEXTFILE

  • Hive数据表的默认格式

存储方式:行存储。

数据不做压缩,磁盘开销大,数据解析开销大。

可结合Gzip、Bzip2使用(系统自动检查,执行查询时自动解压),但使用这种方式,hive不会对数据进行切分,从而无法对数据进行并行操作。



create table if not exists textfile_table(
id int,
name  string,
age   int)
row format delimited
fields terminated by ','
stored as textfile;



插入数据操作:(map/reduce 输出压缩)



GZip和BZip2压缩格式是hadoop版本支持的,而且linux本地的库也支持这种格式的压缩和解压缩。



SEQUENCEFILE

Hadoop API提供的一种二进制文件,以key-value的形式序列化到文件中。



set hive.exec.compress.output=true;  
set mapred.output.compress=true;  
set mapred.output.compression.codec=org.apache.hadoop.io.compress.GzipCodec;  
set io.compression.codecs=org.apache.hadoop.io.compress.GzipCodec;

insert overwrite table textfile_table select * from source_table;



存储方式:行存储。

其具有使用方便、可分割、可压缩的特点。

SequenceFile支持三种压缩选择:NONE,RECORD,BLOCK。Record压缩率低,一般建议使用BLOCK压缩。

压缩数据文件可以节省磁盘空间,但Hadoop中有些原生压缩文件的缺点之一就是不支持分割。支持分割的文件可以并行的有多个mapper程序处理大数据文件,大多数文件不支持可分割是因为这些文件只能从头开始读。Sequence File是可分割的文件格式,支持Hadoop的block级压缩。



create table if not exists seqfile_table(
id int,
name  string,
age   int)
row format delimited
fields terminated by ','
stored as sequencefile;



插入数据操作:



set hive.exec.compress.output=true;  
set mapred.output.compress=true;  
set mapred.output.compression.codec=org.apache.hadoop.io.compress.GzipCodec;  
set io.compression.codecs=org.apache.hadoop.io.compress.GzipCodec;  
SET mapred.output.compression.type=BLOCK;
insert overwrite table seqfile_table select * from source_table;



RCFILERCFILE是一种行列存储相结合的存储方式。首先,其将数据按行分块,保证同一个record在一个块上,避免读一个记录需要读取多个block。其次,块数据列式存储,有利于数据压缩和快速的列存取。



create table if not exists rcfile_table(
id int,
name  string,
age   int)
row format delimited
fields terminated by ','
stored as rcfile;

插入数据操作:


set hive.exec.compress.output=true;  
set mapred.output.compress=true;  
set mapred.output.compression.codec=org.apache.hadoop.io.compress.GzipCodec;  
set io.compression.codecs=org.apache.hadoop.io.compress.GzipCodec; 

insert overwrite table rcfile_table select * from source_table;

相比TEXTFILE和SEQUENCEFILE,RCFILE由于列式存储方式,数据加载时性能消耗较大,但是具有较好的压缩比和查询响应。数据仓库的特点是一次写入、多次读取,因此,整体来看,RCFILE相比其余两种格式具有较明显的优势。

  • ORCFile存储格式
    就是OptimizedRC File的缩写。意指优化的RCFile存储格式。
    hive/spark都支持这种存储格式,它存储的方式是采用数据按照行分块,每个块按照列存储,其中每个块都存储有一个索引。特点是数据压缩率非常高。