Hive的数据存储

Hive的数据存储

  • 基于HDFS
  • 表没有专门的数据存储格式
  • 存储结构主要包括:数据库 文件 表 视图
  • 可以直接接在文本文件(.txt)
  • 创建表时,指定Hive数据的列分隔符和行分隔符

  • 内部表 Table
  • 分区表 Partition
  • 外部表 External Table
  • 桶表 Bucket Table

内部表Table

  • 与数据库中的Table在概念上是类似的
  • 每一个Table在Hive中都有一个相应的目录存储数据
  • 所有的Table数据(不包括External Table)都存在这个目录中
  • 删除表时,元数据与数据都会删除

默认保存在/user/hive/warehouse
Hive的数据存储制定保存的位置
Hive的数据存储
制定 , 分割
Hive的数据存储
创建表的时候同时添加数据
Hive的数据存储
Hive的数据存储
对t4表进行 , 分割

Hive的数据存储
Hive的数据存储

在已有表上添加列
Hive的数据存储
删除表

drop table;

分区表Partition

  • Partition对应于数据库的Partition列的密集索引
  • 在Hive中,表的一个Partition对应一个目录

对学生性别进行分区
Hive的数据存储
Hive的数据存储

//插入数据
insert into table partition_table partion(gender='M')select sid,sname from sample_data where gender = 'M';
insert into table partition_table partion(gender='F')select sid,sname from sample_data where gender = 'F';

Hive的数据存储
查询的时候,查询到具体的分区条件,执行计划就会简便


外部表External Table

  • 指向已经在HDFS中存储的数据,可以建立Partition
  • 与内部表在元数据存储上相同,实际数据存储有较大差异
  • 外部表只是一个过程,加载数据和创建表同时完成,不会转移到数据仓库中,只是与外部数据建立一个链接,删除一个外部表时,仅仅删除该链接

三个文件放入HDFS
Hive的数据存储
Hive的数据存储

桶表 Bucket Table

  • Bucket Table是对数据进行Hash运算,放到不同的文件中
    Hive的数据存储
    创建5个桶(分类)的桶表
    Hive的数据存储

视图

  • 视图是一个虚表,可以跨越多张表,是一个逻辑概念
  • 视图是不存数据的,从视图查出来的数据都来自他所依赖的表,
  • :::基表::: :依赖的表
    Hive的数据存储
    视图查询
    Hive的数据存储
    视图只是简便查询
物化视图

视同中插入数据,就是物化视图
mysql oracle是支持物化视图的
Hive目前不支持物化视图




文件存储格式

STORED AS …


1.textfile

默认格式,建表时不指定默认为这个格式
存储方式:行存储

优点:可以直接读取

缺点:磁盘开销大 数据解析开销大。压缩的text文件 hive无法进行合并和拆分

2.sequencefile
二进制文件,以<key,value>的形式序列化到文件中
存储方式:行存储

缺点:存储空间消耗最大
优点:可分割 压缩,全表时查询效率高
一般选择block压缩,文件和Hadoop api中的mapfile是相互兼容的。EQUENCEFILE将数据以<key,value>的形式序列化到文件中。序列化和反序列化使用Hadoop 的标准的Writable 接口实现。key为空,用value 存放实际的值, 这样可以避免map 阶段的排序过程。三种压缩选择:NONE, RECORD, BLOCK。 Record压缩率低,一般建议使用BLOCK压缩。使用时设置参数,

SET hive.exec.compress.output=true;
SET io.seqfile.compression.type=BLOCK; – NONE/RECORD/BLOCK
create table test2(str STRING) STORED AS SEQUENCEFILE;
3.rcfile
一种行列存储相结合的存储方式。首先,其将数据按行分块,保证同一个record在一个块上,避免读一个记录需要读取多个block。其次,块数据列式存储,有利于数据压缩和快速的列存取。 理论上具有高查询效率(但hive官方说效果不明显,只有存储上能省10%的空间,所以不好用,可以不用)。
RCFile结合行存储查询的快速和列存储节省空间的特点
1)同一行的数据位于同一节点,因此元组重构的开销很低;
2) 块内列存储,可以进行列维度的数据压缩,跳过不必要的列读取。
查询过程中,在IO上跳过不关心的列。实际过程是,在map阶段从远端拷贝仍然拷贝整个数据块到本地目录,也并不是真正直接跳过列,而是通过扫描每一个row group的头部定义来实现的。但是在整个HDFS Block 级别的头部并没有定义每个列从哪个row group起始到哪个row group结束。所以在读取所有列的情况下,RCFile的性能反而没有SequenceFile高。
优点:压缩快, 快速列存取, 读记录尽量涉及到的block最少 ,读取需要的列只需要读取每个row group 的头部定义。
缺点:读取全量数据的操作 性能可能比sequencefile没有明显的优势。但是如果指定一列的话,效率最高

4.orc

存储方式:数据按行分块 每块按照列存储

压缩快 快速列存取

效率比rcfile高,是rcfile的改良版本

5.自定义格式
用户可以通过实现inputformat和 outputformat来自定义输入输出格式。

总结:
textfile 存储空间消耗比较大,并且压缩的text 无法分割和合并 查询的效率最低,可以直接存储,加载数据的速度最高
sequencefile 存储空间消耗最大,压缩的文件可以分割和合并 查询效率高,需要通过text文件转化来加载
rcfile 存储空间最小,查询的效率最高 ,需要通过text文件转化来加载,加载的速度最低

=============================================================

小训练

创建内部表:
    其中有id,name,ip字段,请创建一张普通表,并为各字段添加说明

        create table t1
        (id int,name string,ip double);

创建外部表:
    使用textfile存储方式,以","作为分隔符

        create external table t2
        (id int,name string,ip double)
        row format delimited fields terminated by ','
        STORED AS testfile;

创建分区表:
    分为year,month两个分区,以","作为分隔符,以sequencefile方式存储

        create table partition_table
        (id int,name string,ip double)
        partition by (time string)
        STORED AS sequencefile;

        insert into partition_table partition(time='year')select id,name,ip form t1 where time = 'year';
        insert into partition_table partition(time='month')select id,name,ip form t1 where time = 'month';

创建桶表:
    在year,month的分区之上创建桶,按id的hash值,分为四个桶

        create table bucket_table
        (id int,name string,ip double)
        clustered by(time) into 4 buckets;