Dynamic Partitions

Documentation

这是 Hive 中动态分区的design文档。使用信息也可用:

References:

Terminology

Syntax

在 partition 子句中,以与 SP 列相同的方式指定 DP 列。唯一的区别是 DP 列没有值,而 SP 列却没有。在 partition 子句中,我们需要指定所有分区列,即使它们都是 DP 列也是如此。

在 INSERT ... SELECT ...查询中,必须在 SELECT 语句的列中“最后指定” 动态分区列,并 它们在 PARTITION()子句中出现的 Sequences**。

INSERT OVERWRITE TABLE T PARTITION (ds, hr) 
   SELECT key, value, ds, hr FROM srcpart WHERE ds is not null and hr>10;
INSERT OVERWRITE TABLE T PARTITION (ds='2010-03-03', hr) 
   SELECT key, value, /*ds,*/ hr FROM srcpart WHERE ds is not null and hr>10;
-- 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;
FROM S
   INSERT OVERWRITE TABLE T PARTITION (ds='2010-03-03', hr) 
   SELECT key, value, ds, hr FROM srcpart WHERE ds is not null and hr>10
   INSERT OVERWRITE TABLE R PARTITION (ds='2010-03-03, hr=12)
   SELECT key, value, ds, hr from srcpart where ds is not null and hr = 12;
CREATE TABLE T (key int, value string) PARTITIONED BY (ds string, hr int) AS 
   SELECT key, value, ds, hr+1 hr1 FROM srcpart WHERE ds is not null and hr>10;

上面的示例显示了 CTAS 中所有 DP 列的情况。如果要在某些分区列中放置常量,则可以在选择子句中指定它。例如,

CREATE TABLE T (key int, value string) PARTITIONED BY (ds string, hr int) AS 
   SELECT key, value, "2010-03-03", hr+1 hr1 FROM srcpart WHERE ds is not null and hr>10;

Design

Design issues

1)动态分区列的数据类型:
动态分区列可能是表达式的结果。例如:

-- part_col is partitioning column
 create table T as select a, concat("part_", part_col) from S where part_col is not null;

尽管当前对分区列的数据类型没有限制,但允许非原始列成为分区列可能没有任何意义。动态分区列的类型应从表达式派生。数据类型必须能够转换为字符串才能保存为 HDFS 中的目录名称。

2)将列值分区为目录名称转换:
将列值转换为字符串后,我们仍然需要将字符串值转换为有效的目录名称。原因如下:

我们需要定义一个 UDF(例如 hive_qname_partition(T.part_col)),以获取基本类型的值并将其转换为合格的分区名称。

3)由于 2),此动态分区方案符合基于哈希的分区方案,但我们将哈希函数定义为与
Importing 值。我们应该允许用户为分区哈希函数插入自己的 UDF。如果有足够的兴趣,将提交跟进 JIRA。

4)如果有多个分区列,则它们的 Sequences 很重要,因为这会转换为 HDFS 中的目录结构:按(ds 字符串,dept int)进行分区意味着 ds = 2009-02-26/dept = 2 的目录结构。在涉及分区表的 DML 或 DDL 中,因此,如果指定了分区列的子集(静态),则动态分区列较低时,我们将引发错误。例:

create table nzhang_part(a string) partitioned by (ds string, dept int);
 insert overwrite nzhang_part (dept=1) select a, ds, dept from T where dept=1 and ds is not null;
首页