Hive 动态分区案例

  Hive中支持两种类型的分区:

  • 静态分区SP(static partition)
  • 动态分区DP(dynamic partition)

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

二)实战演示如何在Hive中使用动态分区

1、创建一张分区表,包含两个分区dt和ht表示日期和小时


 
CREATE TABLE partition_table001

(

name STRING,

ip STRING

)

PARTITIONED BY (dt STRING, ht STRING)

ROW FORMAT DELIMITED FIELDS TERMINATED BY "\t

2、启用hive动态分区,只需要在hive会话中设置两个参数:


 
set hive.exec.dynamic.partition=true;

set hive.exec.dynamic.partition.mode=nonstrict;

或者在HIve文件中hive-site.xml中设置:


<property>
    <name>hive.exec.dynamic.partition</name>
    <value>true</value>
    <description>Whether or not to allow dynamic partitions in DML/DDL.</description>
</property>
<property>
    <name>hive.exec.dynamic.partition.mode</name>
    <value>nonstrict</value>
    <description>
      In strict mode, the user must specify at least one static partition
      in case the user accidentally overwrites all partitions.
      In nonstrict mode all partitions are allowed to be dynamic.
    </description>
</property>

3、把partition_table001表某个日期分区下的数据load到目标表partition_table002

使用静态分区时,必须指定分区的值,如:


 
create table if not exists partition_table002 like partition_table001;


insert overwrite table partition_table002 partition (dt='20150617', ht='00') select name, ip from partition_table001 where dt='20150617' and ht='00';

此时我们发现一个问题,如果希望插入每天24小时的数据,则需要执行24次上面的语句。而动态分区会根据select出的结果自动判断数据改load到哪个分区中去。

4、使用动态分区

insert overwrite table partition_table002 partition (dt, ht) select * from partition_table001 where dt='20150617';  

hive先获取select的最后两个位置的dt和ht参数值,然后将这两个值填写到insert语句partition中的两个dt和ht变量中,即动态分区是通过位置来对应分区值的。原始表select出来的值和输出partition的值的关系仅仅是通过位置来确定的,和名字并没有关系,比如这里dt和st的名称完全没有关系。

三)静态分区和动态分区可以混合使用

1、全部DP


 
INSERT OVERWRITE TABLE T PARTITION (ds, hr)

SELECT key, value, ds, hr FROM srcpart WHERE ds is not null and hr>10;

2、DP/SP结合
 

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;

 

3、当SP是DP的子分区时,以下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;

4、多张表插入


 
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;

5、CTAS,(CREATE-AS语句),DP与SP下的CTAS语法稍有不同,因为目标表的schema无法完全的从select语句传递过去。这时需要在create语句中指定partition列 


 
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;

6、上面展示了DP下的CTAS用法,如果希望在partition列上加一些自己的常量,可以这样做


 
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;

四)小结:

通过上面的案例,我们能够发现使用hive中的动态分区特性的最佳实践:对于那些存在很大数量的二级分区的表,使用动态分区可以非常智能的加载表,而在动静结合使用时需要注意静态分区值必须在动态分区值的前面

### Hive 动态分区概述 Hive动态分区是一种高效的数据管理机制,用于优化大规模数据集的存储和查询性能。它通过从输入数据中自动提取分区字段的值来创建分区,从而减少了人工干预并提高了灵活性[^3]。 #### 动态分区的核心概念 动态分区的主要特点是能够根据数据本身的属性自动生成分区结构,而不是依赖于用户的显式定义。这种特性使得动态分区非常适合处理具有高维度特征或者频繁更新的数据源。例如,在日志分析场景下,可以根据时间戳字段(如 `year`、`month` 和 `day`)动态生成对应的目录层次结构[^1]。 #### 动态分区的工作原理 当执行带有动态分区功能的 SQL 或者 ETL 脚本时,Hive 会扫描每一条记录,并从中抽取指定列作为目标路径的一部分。具体流程如下: - **读取数据**:加载待写入的目标表或临时文件。 - **解析元数据**:识别哪些列为动态分区键以及它们可能包含的不同值集合。 - **构建物理布局**:基于这些唯一标识符形成相应的 HDFS 子目录树形图谱。 - **完成持久化操作**:最终将各条目按照既定规则存放到相应位置上[^3]。 #### 启用与配置动态分区 要充分利用这一强大工具,则需调整若干系统级参数以支持其运行环境需求: ```sql SET hive.exec.dynamic.partition=true; -- 开启动态分区开关,默认关闭状态为 false SET hive.exec.dynamic.partition.mode=nonstrict; -- 改变模式至宽松形式 (Strict Mode 下不允许全部采用未知 key 插入新节点),推荐生产环境下设为此选项以便更灵活应对各种情况下的业务逻辑变更需求; ``` 以上命令片段展示了如何激活 Hive 表上的动态分区能力及其关联行为控制项设置过程[^2]。 #### 实际案例演示 下面提供了一个简单的例子说明怎样利用动态分区技术简化日常作业开发工作量的同时提升整体效率水平: 假设我们有一个名为 sales_data 的原始销售明细清单表格,其中包含了日期(date),地区(area)等多个维度的信息.现在希望通过 date 字段实现按天粒度切分后的结果保存到新的汇总统计报表型 fact_table 当中去. ```sql CREATE TABLE IF NOT EXISTS fact_table ( product STRING, amount DOUBLE ) PARTITIONED BY (`date` STRING); INSERT OVERWRITE TABLE fact_table PARTITION(`date`) SELECT product, SUM(amount), date -- 此处即为我们希望依据该字段来进行自动化分配的具体实例体现. FROM sales_data GROUP BY product,date ; ``` 此脚本不仅实现了基本的功能诉求——即将不同时间段内的交易金额累加起来分别展示出来;更重要的是借助内置算法完成了整个过程中涉及的所有必要步骤(比如判断是否存在对应子文件夹如果不存在则先行建立然后再继续后续动作等等).因此极大地降低了人为失误风险同时也加快了程序运转速度.
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值