hive静态分区和动态分区的详解
需要建立一个备份带分区的数据表,拷贝时若采用静态分区方式需要写 N 行语句,因此可以使用动态分区,节省大量时间。
Hive 的分区方式:由于 Hive 实际是存储在 HDFS 上的抽象,Hive 的一个分区名对应一个目录名,子分区名就是子目录名,并不是一个实际字段。
一、hive中支持两种类型的分区
- 静态分区 (static partition)
- 动态分区 (dynamic partition)
静态分区与动态分区的主要区别在于静态分区是手动指定,而动态分区是通过数据来进行判断。详细来说,静态分区的列实在编译时期,通过用户传递来决定的;动态分区只有在 SQL 执行时才能决定。
二、实战演示如何在hive中使用动态分区
1、创建一张分区表,包含两个分区 dt 和 ht 表示日期和小时
hive> create table part1_t1(
> name string,
> ip string
> )
> partitioned by (dt string,ht string)
> row format
> row format delimited fields terminated by ' '
> ;
OK
2、启用hive动态分区,只需要在hive会话中设置两个参数
hive> set hive.exec.dynamic.partition=true;
hive> set hive.exec.dynamic.partition.mode=nonstrict;
- 注意,动态分区不允许主分区采用动态列而副分区采用静态列,这样将导致所有的主分区都要创建副分区静态列所定义的分区。hive.exec.dynamic.partition.mode它的默认值是 strick,即不允许分区列全部是动态的,这是为了防止用户有可能原意是只在子分区内进行动态建分区,但是由于疏忽忘记为主分区列指定值了,这将导致一个 dml 语句在短时间内创建大量的新的分区(对应大量新的文件夹),对系统性能带来影响。?
- strict 于 nonstrict 区别:strict是严格的,在动态分区表中插入分区数据需要提前在,动态分区表中建立一个静态分区。而nonstrict不需要,
3、把part1_t1 表示某个日期分区下的数据load到目标表 part1_t2使用静态分区时必须 指定分区,如:
create table if not exists part1_t2 like part1_t1;
insert table part1_t2 partition (dt='20190506',ht='00') select name,ip from part1_t1 where dt='20150506' and ht='00';
此时我们会发现一个问题,如果希望插入每天 24 小时的数据,则需要执行 24 次上面的语句。而动态分区会根据 select 出的结果自动判断数据改 load 到哪个分区中去。
4、使用动态分区
只需要一句hql即可包20150506下的24个ht分区插入新表中
insert table part1_t1 partition(dt,ht) select * from
part1_t1 where dt='20150506';
过程说明:
hive 先获取 select 的最后两个位置的 dt 和 ht 参数值,然后将这两个值填写到 insert 语句 partition 中的两个 dt 和 ht 变量中,即动态分区是通过位置来对应分区值的。原始表 select 出来的值和输出 partition 的值的关系仅仅是通过位置来确定的,和名字并没有关系,比如这里 dt 和 st 的名称完全没有关系。
三、静态分区和动态分区可以混合使用
1、only动态分区
insert table1 partition (dt,ht) select key,value form table2 [where ...]
2、动态分区和静态分区结合
insert table1 partition (dt='20160507',ht) select key value from table2 [where..]
注意:当静态分区时动态分区的子分区的时候,以下的DML会抱错。因为分区的顺序决定了HDFS中目录的继承关系,这是无法该改变的。
-- throw an exception
INSERT OVERWRITE TABLE T PARTITION (ds, hr = 11)
SELECT key, value, ds/*, hr*/ FROM srcpart WHERE ds is not null and hr=11;
四、hive的严格模式
1、配置信息
<property>
<name>hive.mapred.mode</name>
<value>nonstrict</value>
<description>
The mode in which the Hive operations are being performed.
In strict mode, some risky queries are not allowed to run. They include:
Cartesian Product.
No partition being picked up for a query.
Comparing bigints and strings.
Comparing bigints and doubles.
Orderby without limit.
</description>
</property>
严格模式阻挡5类查询:
1、笛卡尔积
set hive.mapred.mode=strict;
select
*
from dy_part1 d1
join dy_part2 d2
;
2、分区表没有分区字段过滤
set hive.mapred.mode=strict;
select
*
from dy_part1 d1
where d1.dt='2019-09-09'
;
不行
select
*
from dy_part1 d1
where d1.id > 2
;
select
*
from dy_part2 d2
where d2.year >= 2019
;
3、order by不带limit查询
select
*
from log3
order by id desc
;
4、(bigint和string比较)Comparing bigints and strings.
5、(bigint和double比较)Comparing bigints and doubles.