关系型数据库(如Oracle)中,对分区表Insert数据时候,数据库自动会根据分区字段的值,将数据插入到相应的分区中,Hive中也提供了相似的机制,即动态分区(Dynamic Partition),只不过,使用Hive的动态分区,须要进行相应的配置。node
先看一个应用场景,源表t_lxw1234的数据以下:数据库
目标表为:url
需求:将t_lxw1234中的数据按照时间(day),插入到目标表t_lxw1234_partitioned的相应分区中。it
若是按照以前介绍的往指定一个分区中Insert数据,那么这个需求很不容易实现。io
这时候就须要使用动态分区来实现,使用动态分区须要注意设定如下参数:table
默认值:false配置
是否开启动态分区功能,默认false关闭。file
使用动态分区时候,该参数必须设置成true;error
默认值:strict数据
动态分区的模式,默认strict,表示必须指定至少一个分区为静态分区,nonstrict模式表示容许全部的分区字段均可以使用动态分区。
通常须要设置为nonstrict
默认值:100
在每一个执行MR的节点上,最大能够建立多少个动态分区。
该参数须要根据实际的数据来设定。
好比:源数据中包含了一年的数据,即day字段有365个值,那么该参数就须要设置成大于365,若是使用默认值100,则会报错。
默认值:1000
在全部执行MR的节点上,最大一共能够建立多少个动态分区。
同上参数解释。
默认值:100000
整个MR Job中,最大能够建立多少个HDFS文件。
通常默认值足够了,除非你的数据量很是大,须要建立的文件数大于100000,可根据实际状况加以调整。
默认值:false
当有空分区生成时,是否抛出异常。
通常不须要设置。
那么,上面的需求可使用以下的语句来完成:
注意:在PARTITION (month,day)中指定分区字段名便可;
在SELECT子句的最后两个字段,必须对应前面PARTITION (month,day)中指定的分区字段,包括顺序。
执行结果以下:
Loading data to table liuxiaowen.t_lxw1234_partitioned partition (month=null, day=null)
Loading partition {month=2015-05, day=2015-05-10}
Loading partition {month=2015-06, day=2015-06-14}
Loading partition {month=2015-06, day=2015-06-15}
Partition liuxiaowen.t_lxw1234_partitioned{month=2015-05, day=2015-05-10} stats: [numFiles=1, numRows=2, totalSize=10, rawDataSize=8]
Partition liuxiaowen.t_lxw1234_partitioned{month=2015-06, day=2015-06-14} stats: [numFiles=1, numRows=2, totalSize=10, rawDataSize=8]
Partition liuxiaowen.t_lxw1234_partitioned{month=2015-06, day=2015-06-15} stats: [numFiles=1, numRows=2, totalSize=10, rawDataSize=8]
使用show partitions t_lxw1234_partitioned;查看目标表有哪些分区:
hive> show partitions t_lxw1234_partitioned;
OK
month=2015-05/day=2015-05-10
month=2015-06/day=2015-06-14
month=2015-06/day=2015-06-15