hive 分区总结

一、分区的核心概念

Hive 的分区 本质是按指定字段将数据文件划分到不同的 HDFS 目录 (比如按日期dt=20260106、按地区region=cn),核心目的是:

  • 避免全表扫描,只扫描指定分区的数据,大幅提升查询效率;
  • 方便数据按业务维度(时间 / 地区 / 部门)管理。

关键特点

  • 分区字段是伪列(不在数据文件的真实列中),仅用于划分目录;
  • 分区表创建时需用PARTITIONED BY (分区字段 数据类型)声明。

二、静态分区(Static Partition)

1. 核心定义

静态分区指插入 / 加载数据时,分区字段的值是手动指定的固定值 (比如明确指定dt='20260106'),适用于分区值已知且固定的场景。

2. 操作示例
步骤 1:创建分区表

以 "学生成绩表" 为例,按班级(class)分区:

sql

复制代码
-- 创建分区表(管理表)
CREATE TABLE score (
    id INT,          -- 学生ID(真实列)
    name STRING,     -- 学生姓名(真实列)
    score INT        -- 成绩(真实列)
) 
PARTITIONED BY (class STRING)  -- 分区字段:班级(伪列)
ROW FORMAT DELIMITED FIELDS TERMINATED BY '\t'  -- 数据分隔符为制表符
STORED AS TEXTFILE;  -- 文件格式
步骤 2:加载数据到静态分区

有两种常见方式:LOAD DATA(加载文件)和INSERT...SELECT(插入查询结果)。

方式 1:LOAD DATA 加载本地文件到静态分区

假设本地有文件/root/score_2201.txt,内容为:

plaintext

复制代码
1	张三	90
2	李四	85
3	王五	92

执行以下 SQL,将数据加载到class=2201分区:

sql

复制代码
LOAD DATA LOCAL INPATH '/root/score_2201.txt' 
INTO TABLE score 
PARTITION (class='2201');  -- 手动指定分区值(静态)
方式 2:INSERT...SELECT 插入数据到静态分区

假设已有表score_all,包含所有班级数据,现在将 2202 班数据插入到静态分区:

sql

复制代码
INSERT OVERWRITE TABLE score 
PARTITION (class='2202')  -- 手动指定分区值(静态)
SELECT id, name, score FROM score_all WHERE class='2202';
步骤 3:查询静态分区数据

sql

复制代码
-- 只扫描2201分区,效率高
SELECT * FROM score WHERE class='2201';

三、动态分区(Dynamic Partition)

1. 核心定义

动态分区指插入数据时,分区字段的值由查询结果自动推导(无需手动指定),适用于分区值未知、需批量处理多个分区的场景(比如按日期批量导入近 30 天数据)。

2. 前置配置(必须)

动态分区默认关闭,需先设置以下参数:

sql

复制代码
-- 开启动态分区(默认false)
SET hive.exec.dynamic.partition=true;
-- 设置为非严格模式(默认strict,要求至少一个静态分区,nonstrict允许全动态)
SET hive.exec.dynamic.partition.mode=nonstrict;
-- 可选:设置每个节点允许的最大动态分区数(防止分区过多)
SET hive.exec.max.dynamic.partitions.pernode=1000;
3. 操作示例

延续上面的score表,现在需要将score_all中的所有班级数据自动按班级分区插入(无需手动指定每个班级)。

步骤 1:准备源表数据

假设score_all表内容:

id name score class
1 张三 90 2201
2 李四 85 2201
3 王五 92 2202
4 赵六 88 2202
5 钱七 95 2203
步骤 2:插入数据到动态分区

sql

复制代码
-- 动态分区:分区字段class的值由SELECT结果的最后一列自动推导
INSERT OVERWRITE TABLE score 
PARTITION (class)  -- 仅声明分区字段,不指定值(动态)
SELECT id, name, score, class FROM score_all;  -- 最后一列必须是分区字段class

关键说明

  • PARTITION (class) 仅声明分区字段,不写值;
  • SELECT语句的最后一列必须是分区字段 (这里是class),Hive 会根据该列的值自动创建对应分区(2201/2202/2203)。
步骤 3:验证动态分区结果

sql

复制代码
-- 查看所有分区
SHOW PARTITIONS score;
-- 输出:
-- class=2201
-- class=2202
-- class=2203

-- 查询2203分区数据
SELECT * FROM score WHERE class='2203';
-- 输出:
-- 5	钱七	95	2203

四、静态分区 vs 动态分区 对比

维度 静态分区 动态分区
分区值指定 手动固定值 由查询结果自动推导
适用场景 单个 / 少量已知分区 批量 / 未知分区(如按日期批量)
配置要求 无需额外配置 需开启动态分区参数
语法特点 PARTITION (class='2201') PARTITION (class)

总结

  1. 分区的核心价值:将数据按业务维度(如班级 / 日期)拆分到不同目录,避免全表扫描,提升查询效率;
  2. 静态分区:分区值手动指定,适合少量、已知分区的场景,无需额外配置;
  3. 动态分区 :分区值自动推导,适合批量、未知分区的场景,需先开启nonstrict模式,且 SELECT 最后一列必须是分区字段。
相关推荐
SelectDB技术团队1 天前
上市大模型企业数据基础设施的选择:MiniMax 基于阿里云 SelectDB 版,打造全球统一AI可观测中台
数据库·数据仓库·人工智能·ai·apache
weixin_462446231 天前
Hive Metastore 使用 MySQL 8(CJ 驱动)完整配置实战(含完整 Shell 脚本)
hive·hadoop·mysql
zgl_200537791 天前
源代码:ZGLanguage 解析SQL数据血缘 之 显示 MERGE SQL 结构图
数据库·数据仓库·hive·数据治理·etl·sql解析·数据血缘
Gain_chance1 天前
24-学习笔记尚硅谷数仓搭建-DIM层的维度表建表思路及商品表维度表的具体建表解析
数据仓库·hive·笔记·学习·datagrip
编程小风筝1 天前
MySQL数据库如何实现实现数据仓库存储?
数据库·数据仓库·mysql
talle20211 天前
Hive | 分区与分桶
大数据·数据仓库·hive
zhangkaixuan4562 天前
Paimon 读取数据流程深度解析
大数据·hadoop·flink·apache·paimon
Gain_chance2 天前
23-学习笔记尚硅谷数仓搭建-ODS层业务全量表、增量表结构设计及数据装载脚本
数据仓库·hive·笔记·学习
JZC_xiaozhong2 天前
什么是ETL?一文了解提取、转换与加载
数据库·数据仓库·数据分析·etl·数据一致性·数据孤岛解决方案·数据集成与应用集成
yumgpkpm2 天前
在AI语言大模型时代 Cloudera CDP(华为CMP 鲲鹏版)对自有知识的保护
人工智能·hadoop·华为·zookeeper·spark·kafka