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 最后一列必须是分区字段。
相关推荐
淡定一生23333 小时前
数据仓库中的退化维度
数据仓库
smchaopiao9 小时前
Hive中的排序与分桶技术详解
数据仓库·hive·hadoop
tsyjjOvO3 天前
SpringMVC 从入门到精通
数据仓库·hive·hadoop
Francek Chen3 天前
【大数据存储与管理】分布式数据库HBase:05 HBase运行机制
大数据·数据库·hadoop·分布式·hdfs·hbase
zzzzzwbetter3 天前
Hadoop完全分布式部署-Master的NameNode以及Slaver2的DataNode未启动
大数据·hadoop·分布式
weixin_449310843 天前
ETL转换和数据写入小满OKKICRM的技术细节
数据仓库·php·etl
IvanCodes4 天前
Hive IDE连接及UDF实战
ide·hive·hadoop
yumgpkpm4 天前
华为昇腾910B 开源软件GPUStack的介绍(Cloudera CDH、CDP)
人工智能·hadoop·elasticsearch·flink·kafka·企业微信·big data
lifewange4 天前
Hive数据库
数据库·hive·hadoop
五月天的尾巴5 天前
hive数据库模糊查询表名
hive·查询表名