需要建立一个备份带分区的数据表,拷贝时若采用静态分区方式需要写 N 行语句,因此可以使用动态分区,节省大量时间。
Hive 的分区方式:由于 Hive 实际是存储在 HDFS 上的抽象,Hive 的一个分区名对应一个目录名,子分区名就是子目录名,并不是一个实际字段。
静态分区与动态分区的主要区别在于静态分区是手动指定,而动态分区是通过数据来进行判断。详细来说,静态分区的列实在编译时期,通过用户传递来决定的;动态分区只有在 SQL 执行时才能决定。
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;
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 的名称完全没有关系。
insert table1 partition (dt,ht) select key,value form table2 [where ...]
insert table1 partition (dt='20160507',ht) select key value from table2 [where..]
-- 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.mapred.mode
nonstrict
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.
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.