Hive学习笔记五:表的类型、视图、索引以及加载方式

Hive表的类型

         Hive 的表有哪些类型呢,我们简单可以分为四种,受控表、外部表、分区表、桶表,从严格意义上说,应该分为两种受控表,又叫内部表、外部表,分区表和桶表其实是受控表的不同体现。

1、受控表

        所谓受控表,我们也经常叫内部表,和外部表对应起来,就是说表的数据的生命周期收表的控制,当表定义被删除的时候,表中的数据随之一并被删除。创建一张表,其对应在hive中就有了表记录,在metastore表TBLS中就有表定义,当我们一旦从hive中删除一张表的定义之后,其表中的数据也就不复存在了,在metastore中的定义也就不存在了。

2、外部表

        和受控表相对的,怎么相对呢,你的内部表的数据的生命周期受表定义的影响不是,外部表的不是这样的,数据的生命周期, 或者说数据存在与否和表的定义互不约束,表中的数据呢,只是表对hdfs上相应文件的一个引用而已,当删除表定义的时候,表中的数据依然存在。
        如何创建外部表?
                create external table tblName(colName colType...);
                external,是外部表,必须要和内部表区别一下
        加载数据
                alter table tblName set location 'hdfs_absolute_uri';
                一个是location,不是引用hdfs的数据吗,
                当然在创建表的时候就可以告诉它引用数据的地方
                create external table tblName(colName colType...) location 'hdfs_absolute_uri';

3、分区表

        假设服务器集群每天都产生一个日志数据文件,把数据文件统一存储到HDFS中。我们如果想查询某一天的数据的话,hive执行的时候会对所有文件都扫描一遍,判断是否是指定的日期。可以让日期作为一个子目录。当hive查询的时候,根据日期去判断子目录。然后扫描符合条件的子目录中的数据文件。
        如何创建一张分区表?
        只需要在之前的创建表后面加上分区字段就可以了,
                create table tblName (
                    id int comment 'ID',
                    name string comment 'name'
                ) partitioned by (dt date comment 'create time')
                row format delimited
                fields terminated by '\t';
        如何加载数据?
                load data local inpath linux_fs_path into table tblName partition(dt='2015-12-12');
                上面的语句会在hive表tblName中自动创建一个分区,以dt='2015-12-12'为文件夹名称,下面存放上传的数据
                相应的在metastore中的partitions中就有了相应的记录。
        分区的一些操作:
                查询分区中的数据:select * from tblName where dt='2015-12-13';(分区相当于where的一个条件)
                手动创建一个分区:alter table tblName add partition(dt='2015-12-13');
                查看分区表有哪些分区:show partitions tblName;
                删除一个分区:alter table tblName drop partition(dt='2015-12-12');
        多个分区如何创建?和单分区表的创建类似:
                create table tblName (
                  id int comment 'ID',
                  name string comment 'name'
             ) partitioned by (year int comment 'admission year', school string comment 'school name')
             row format delimited
             fields terminated by '\t';    
            同时也可以从hdfs上引用数据:
                    alter table tblName partition(year='2015', school='crxy') set location hdfs_uri;
            注意:
                    必须得现有分区,必须要使用hdfs绝对路径
                    相应的分区下面没有数据对吧,你删了分区也不会影响原来的数据对不对,有点动态引用的意思。

4、桶表

        桶表是对数据进行哈希取值,然后放到不同文件中存储。分桶是将数据及分解成更容易管理的若干部分的另一种技术。如果进行表连接操作,那么就需要对两张表的数据进行全扫描。非常耗费时间。可以针对连接字段进行优化。分桶这种情况下呢,对于相似的表中的数据进行比较的话就非常的方便了,只要对比相应的桶中的数据就可了。
        如何创建桶表?
                create table tblName_bucket(id int) clustered by (id) into 3 buckets;
            说明:
                clustered by :按照什么分桶
                into x buckets:分成x个桶
        如何加载数据?
            不能使用load data这种方式,需要从别的表来引用
                    insert into table tblName_bucket select * from tbl_other;
            注意:在插入数据之前需要先设置开启桶操作,不然插入数据不会设置为桶!!!
                    set hive.enforce.bucketing=true;
        桶表的主要作用:
            数据抽样
            提高某些查询效率

Hive视图

        Hive中,也有视图的概念,那我们都知道视图实际上是一张虚拟的表,是对数据的逻辑表示,只是一种显示的方式,主要的作用呢:
  1、视图能够简化用户的操作
  2、视图使用户能以多钟角度看待同一数据
        3、视图对重构数据库提供了一定程度的逻辑独立性
        4、视图能够对机密数据提供安全保护
        5、适当的利用视图可以更清晰的表达查询
        那我们在Hive中如何来创建一个视图呢?
                      create view t_view as select * from otherTbl;
        关于视图的几点说明:
        1、只有视图的定义,没有相应的物理结构
            也就是说只有在metastore中有和hdfs中的映射关系,在hdfs中没有相应的文件夹
        2、操作
            可以把视图当做表的一个衍伸,所以对hive表的各种操作,在视图上就有。

hive索引

        索引是标准的数据库技术,hive 0.7版本之后支持索引。Hive提供有限的索引功能,这不像传统的关系型数据库那样有“键(key)”的概念,用户可以在某些列上创建索引来加速某些操作,给一个表创建的索引数据被保存在另外的表中。 Hive的索引功能现在还相对较晚,提供的选项还较少。但是,索引被设计为可使用内置的可插拔的java代码来定制,用户可以扩展这个功能来满足自己的需求。 当然不是说有的查询都会受惠于Hive索引。用户可以使用EXPLAIN语法来分析HiveQL语句是否可以使用索引来提升用户查询的性能。像RDBMS中的索引一样,需要评估索引创建的是否合理,毕竟,索引需要更多的磁盘空间,并且创建维护索引也会有一定的代价。 用户必须要权衡从索引得到的好处和代价。

        创建索引
                create index t1_index on table t1(stu_name) as
                'org.apache.hadoop.hive.ql.index.compact.CompactIndexHandler'
                with deferred rebuild in table t1_index_table;

        重建索引
                alter index t1_index on t1 rebuild;
        显示索引
                show formatted index on t1;
        删除索引
               drop index if exists t1_index on t1;

Hive数据加载方式

        说明:[]表示可有可无,<>表示必须要有
       1°、从linux fs和hdfs中加载
        load data [local] inpath 'path' [overwrite] into table tblName [partition_sepc];
        几个关键字有无的说明:
            local:
                有:数据从本地path中加载,其中path可以是绝对路径,也可以是相对路径。
                无:数据从hdfs上的相应路径path中移动数据到表tblName下,相当于hadoop fs -mv hdfs_uri_1 hdfs_uri_2
            overwrite:
                有:覆盖原来的数据,只保留新上传的数据。
                无:在原来的目录下,在增加一个数据文件。
            partition:
                有:增加到相应的分区中
                无:该表不是分区表
        2°、从其他表中装载
        insert <into|overwrite> table tblName select columns... from otherTblName;
        关于overwrite的含义和上述是一致的。
        唯一一点需要说明的是:
            tblName表中的字段要和后面select查询的字段要保持一致!!!
        3°、通过动态分区装载数据
        如果我们表的分区创建非常多的话,对于我们装载数据是一件非常麻烦的事,Hive提供动态分区来解决这个问题。可以基于查询参数推断出需要创建的分区名称,相比的分区都是静态的,这里就称之为动态的分区。
        怎么来弄呢?
                INSERT overwrite TABLE t3 PARTITION(province='gs', city)
                SELECT t.province, t.city FROM temp t WHERE t.province='gs';
        说明一下:静态分区必须出现在动态分区之前!!!
        我想连province='gs'都省了?
        报错了,需要我们开启动态分区的支持
                set hive.exec.dynamic.partition=true;
                set hive.exec.dynamic.partition.mode=nostrict;
                set hive.exec.max.dynamic.partitions.pernode=1000;
                INSERT overwrite TABLE t3 PARTITION(province, city)
                SELECT t.province, t.city FROM temp t;
        经验说明一点:在创建分区的时候,最好不要创建过多的分区,如果分区过多的话,查询也是非常的慢的,就像在window下一个文件夹下面的文件过多会对我们的使用造成非常的不便的。那么hive能支持多大的分区数呢,可以使用命令
            set hive.exec.max.dynamic.partitions获取
        4、创建表的同时装载数据
        和之前创建视图的时候的语法非常相似,把view改成table就可以
        create table newTblName as select columns from other_tblName;

Hive数据的导出

        这个是数据装载的反向过程,有两种方式
        1°、在hdfs的直接上操作
                hadoop fs -cp src_uri dest_uri
        2°、在终端使用directory
        insert overwrite [local] directory 'linux_fs_path' select ...from... where ...;

Hive本地模式

        之前有些hql语句的执行最后转化为了mr,但是执行的过程非常的慢,如何提高执行效率呢?使用本地模式。
        需要开启本地模式:
                set hive.exec.mode.local.auto=true;
        再去执行相同的hql时,会发现速度提高很多。但是,本地模式主要用来做调试,不能配置到hive-site.xml中,因为本地模式,会只在当前机器上执行mr,但是如果数据量一大,这样会累垮我们的单台节点的。

  • 0
    点赞
  • 26
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值