本文主要总结HIve自身的一些特点,并对其中的一些点和传统数据库做对比,能够更好的理解Hive。
Hive详细入门介绍看下方链接,有原理,有案例,讲的很通俗易懂。
链接易学教程——Hive入门详解
Hive是Hadoop上的数据仓库工具,处理的是结构化数据。注意:定位是数据仓库,所以适用于实时性要求不高的场合。
Facebook设计Hive时针对的业务场景就是处理海量结构化日志。
Hive提供的语言是HQL,类似于SQL,但有一些差别,比如没有update语句,对应的是覆盖语句insert overwrite,等其他差异。
Hive区别于其他大数据技术相关数据库的最大优势是:提供了类似于SQL的语法,容易上手,但是后台实际执行却用了大数据技术。
开发人员在操作接口提交类SQL语法,Hive后台执行时会把HQL语法转化成MapReduce作业。
3.1 Hive提供快速建表语句
create table if not exists student_temp like student;
创建表时可以用 if not exists语句判断表是否存在,可以用like快速复制表结构。这点DB2数据也支持
3.2 Hive表分为内部表和外部表
内部表就是所谓的管理表,是实体表。删除内部表数据也会同时被删除。
外部表并不拥有这份数据,删除表不会删除数据,只会删除外部表的元数据。
其实内部表和外部表类似于传统数据库中表和视图的概念。内部表就是表,外部表相当于视图。
3.3 分区表 partitioned
hive的分区表的相当于在目录下创建多个文件夹存放不同数据。多级分区表就是建多级多个目录。
\table_trx_inf\2018\11
\table_trx_inf\2018\12
\table_trx_inf\2019\01
\table_trx_inf\2019\02
…
交易表table_trx_inf是两级分区表,分区字段是year和month
3.1.1 hive分区表特殊点:
各个分区表在物理上是单独为目录文件,在逻辑上也不是一个表。因为对它操作是要具体某个分区的。
如:
a. 加载数据
load data local inpath '/opt/module/datas/table_trx_inf.txt' into table default.table_trx_inf_partition partition(year='2018',month='11');
b.查询要用union关联
select * from table_trx_inf where year='2018'and month='11'
union
select * from table_trx_inf where year='2019'and month='01'
DB2的分区表在物理上是以单独的数据文件存储,但是在逻辑上是一个表。
交易水表trx_inf是按照月进行分区,
查询或插入数据的时候会根据分区键的值自动判断对具体分区表操作,不用用户具体指定。也可以把某个分区detach拆分出来,操作完后在attach到逻辑表中。
【备注】:上述hive中的分区表是静态分区表,hive也提供了动态分区表。功能同关系型数据库对分区表Insert数据时候,数据库自动会根据分区字段的值,
将数据插入到相应的分区中,Hive中也提供了类似的机制,即动态分区(Dynamic Partition),但需要对动态分区参数进行相应配置。
4. 分桶表 关键词bucket
分区表针对数据存储路径,设置不同存储路径产生多个数据文件。分区提供一个隔离数据和优化查询的方式。
分桶表针对数据文件,对一个数据文件分为更容易管理的若干部分的另一技术。类似于Teradata数据库为表设置PPI。
4.1 多表关联中,每两个表关联一次Hadoop就启动一个MapReduce程序。
正因为用的是MapReduce程序,所以关联到相同key对应的数据会发送到相同reducer上。有的reducer上数据太多会导致内存不够,这时要分析异常key。
尤其是null和空字符串’'的情况,对这种数据进行过滤。
这跟Teradata相似,同一pi的数据会分配到相同AMP上,每个AMP的存储资源,计算资源等相互独立,就会造成数据倾斜,个别AMP上有大量数据,这种情况一般是把高频pi对应的数据和低频pi对应的数据分开单独放到临时表处理,因为数据这部分数据会在所有AMP中进行重分布,避免数据倾斜。
4.2 hive的多表关联中不支持or连词
select a.id,a.name ,b.dept
from table1 as a
join table2 as b
on a.id = b.id
or a.name = b.name ; #错误 可以拆分成和table2关联两次
PS:虽然其他的关系型数据库在关联中支持or谓词,但是尽量少用,可以用同一张表关联多次。因为解析器不能很好的处理or关联条件,生成的执行计划一般不是最优的,影响查询效率。
select a.id,a.name ,coalesce(b.dept,c.dept,'')
from table1 as a
left outer join table2 as b
on a.id = b.id
left outer join table2 as c
on a.name = b.name
; #这是Teradata的写法,个别写法有差异。如DB2中coalesce()函数用values()代替
4.3 count(distinct)去重
count(distinct)在小数据量的情况下没问题。但count(distinct)操作需要用一个Reduce Task来完成,这一个Reduce需要处理的数据量太大,就会导致整个Job很难完成。
大数据集上建议用group by +count()的方式分步处理完成。
举例子:
select count(distinct id)
from bigtable
;
代替方法:
select count(id)
from (select id from bigtable group by id) a
;
注意:最好是能把子查询语句单独建临时表select id from bigtable group by id,这样执行效率更高。
4.4 Hive的严格模式
Hive提供的严格模式,防止用户执行那些意向不到的不好影响的查询。什么意思呢?就是有些语句在语法上是没问题,但是逻辑上不对的语句。
严格模式就是根据表类型或数据情况加了一些检测,即使语法正确,检测不通过也不让执行。具体看下面严格模式限制的内容就一目了然了:
4.4.1 分区表必须使用分区字段
如果查询表是分区表,但是where条件中没用到分区字段,这种查询语句就不让执行。
因为分区表都是非常大的数据集,不加分区字段全表扫描不但执行效率极低还影响整个数据库性能。
4.4.2 order by语句查询必须使用limit语句
因为order by为了执行排序过程会将所有的结果数据分发到同一个Reducer中进行处理,强制要求用户增加这个LIMIT语句可以防止Reducer额外执行很长一段时间。
4.4.3 限制笛卡尔积的查询。
关系型数据库可以将where条件转化为on条件,但是Hive没有这种优化,表足够大时出现不可控局面。
关系型数据库支持如下写法可以把where条件转化为on条件
select a.id, b.dept_name
from emp_if as a
,dept_id as b
where a.dept_id = b.dept_id
;
Hive严格模式还是很有用的,在关系型数据库中也会用这样的需求。