什么动态分区,动态分区好处

动态分区是分区在数据插入的时候,根据某一列的列值动态生成.

往hive分区表中插入数据时,如果需要创建的分区很多,比如以表中某个字段进行分区存储,则需要复制粘贴修改很多sql去执行,效率低。因为hive是批处理系统,所以hive提供了一个动态分区功能,其可以基于查询参数的位置去推断分区的名称,从而建立分区。

静态分区与动态分区的主要区别在于静态分区是手动指定,而动态分区是通过数据来进行判断。详细来说,静态分区的列实在编译时期,通过用户传递来决定的;动态分区只有在SQL执行时才能决定。

准备工作

准备数据

order_created.txt

  1. [root@zjj101 soft]# cat order_created.txt
  2. 10703007267488 2014-05-01 06:01:12.334+01
  3. 10101043505096 2014-05-01 07:28:12.342+01
  4. 10103043509747 2014-05-02 07:50:12.33+01
  5. 10103043501575 2014-05-02 09:27:12.33+01
  6. 10104043514061 2014-05-01 09:03:12.324+01
  7. [root@zjj101 soft]#

新建一个普通的表并装载数据

sql:

  1. -- 创建普通表
  2. create table order_partition
  3. (
  4. order_no string,
  5. order_time string
  6. )
  7. row format delimited fields terminated by '\t';
  8. -- 装载数据
  9. load data local inpath '/root/soft/order_created.txt' into table order_partition;
  10. -- 查询数据是否装载成功
  11. select *
  12. from order_partition;

hive动态分区 - 图1

开始创建分区表

创建单一字段分区表

sql

  1. create table order_dynamic_partition
  2. (
  3. order_no string
  4. )
  5. PARTITIONED BY (time string)
  6. row format delimited fields terminated by '\t';

查询刚刚建的表 sql:

  1. select *
  2. from order_dynamic_partition;

hive动态分区 - 图2

建立动态分区并且装载数据

注意:使用,insert…select 往表中导入数据时,查询的字段个数必须和目标的字段个数相同,不能多,也不能少,否则会报错。但是如果字段的类型不一致的话,则会使用null值填充,不会报错。而使用load data形式往hive表中装载数据时,则不会检查。如果字段多了则会丢弃,少了则会null值填充。同样如果字段类型不一致,也是使用null值填充。

因为分区表只有一个字段 ,我们查询的时候系统默认用最后一个字段为分区名字,为分区表的
分区字段默认也是该表中的字段,且依次排在表中字段的最后面。所以分区需要分区的字段只能放在后面,不能把顺序弄错。如果我们查询了四个字段的话,则会报
错,因为该表加上分区字段也才三个。要注意系统是根据查询字段的位置推断分区名的,而不是字段名称

sql

  1. -- 开启动态分区,默认是false
  2. set hive.exec.dynamic.partition=true;
  3. -- 开启允许所有分区都是动态的,否则必须要有静态分区才能使用。
  4. set hive.exec.dynamic.partition.mode=nostrick;
  5. -- 动态的插入分区表
  6. insert overwrite table order_dynamic_partition
  7. partition (time)

查询分区信息

  1. show partitions order_dynamic_partition;

hive动态分区 - 图3

查询插入好的数据

  1. select order_no, order_time
  2. from order_partition;

hive动态分区 - 图4

半自动分区

多个分区字段时,实现半自动分区(部分字段静态分区,注意静态分区字段要在动态前面)

原始表的数据

  1. select *
  2. from order_partition;

hive动态分区 - 图5

创建两个分区字段的分区表

  1. create table order_a
  2. (
  3. order_no string
  4. ) partitioned by (type string , time string );

以半动态分区插入数据

  1. set hive.exec.dynamici.partition=true;
  2. set hive.exec.dynamic.partition.mode=nonstrict;
  3. insert overwrite table order_a
  4. partition (type = 'china', time) -- type分区为静态,ct为动态分区,以查询的order_time字段为分区名
  5. select order_no, order_time
  6. from order_partition;

查询分区属性

  1. show partitions order_a;

hive动态分区 - 图6

查询数据

  1. select *
  2. from order_a;

hive动态分区 - 图7

接着往分区表插入值

  1. insert overwrite table order_a
  2. partition (type = 'USA', time) -- type分区为静态,ct为动态分区,以查询的order_time字段为分区名
  3. select order_no, order_time
  4. from order_partition;

查询分区属性

sql

  1. show partitions order_a;

hive动态分区 - 图8

查询结果

sql

  1. select *
  2. from order_a ;

hive动态分区 - 图9
sql

  1. select *
  2. from order_a where type = 'USA' ;

hive动态分区 - 图10

多字段全部实现动态分区插入

原始数据表

  1. select *
  2. from order_a;

hive动态分区 - 图11

创建分区表

sql:

  1. create table order_b
  2. (
  3. order_no string
  4. ) partitioned by (type string , time string );

多字段全部动态插入数据

sql

— 注意:字段的个数和顺序不能弄错。

  1. set hive.exec.dynamic.partition=true;
  2. set hive.exec.dynamic.partition.mode=nostrick;
  3. insert overwrite table order_b
  4. partition (type, time)
  5. select order_no, type, `time`
  6. from order_a;

查询导入结果

sql

  1. select *
  2. from order_b;

hive动态分区 - 图12

动态分区表的属性

使用动态分区表必须配置的参数 :

set hive.exec.dynamic.partition =true(默认false),表示开启动态分区功能
set hive.exec.dynamic.partition.mode = nonstrict(默认strict),表示允许所有分区都是动态的,否则必须有静态分区字段

动态分区相关的调优参数:

set hive.exec.max.dynamic.partitions.pernode=100 (默认100,一般可以设置大一点,比如1000) 表示每个maper或reducer可以允许创建的最大动态分区个数,默认是100,超出则会报错。

set hive.exec.max.dynamic.partitions =1000(默认值) 表示一个动态分区语句可以创建的最大动态分区个数,超出报错

set hive.exec.max.created.files =10000(默认) 全局可以创建的最大文件个数,超出报错。