本文基于 Hive 分区表相关内容整理,涵盖分区表语法、分区操作、二级分区表以及动态分区等常用知识点。
一、分区表语法格式
CREATE [TEMPORARY] [EXTERNAL] TABLE [IF NOT EXISTS] [db_name.]table_name
[(col_name data_type [column_constraint_specification] [COMMENT col_comment], ... [constraint_specification])]
[COMMENT table_comment]
[PARTITIONED BY (col_name data_type [COMMENT col_comment], ...)] -- 分区表关键字
[ROW FORMAT row_format]
案例
-- 创建分区表
CREATE TABLE IF NOT EXISTS dept_partition(
deptno INT COMMENT '部门编号',
dname STRING COMMENT '部门名称',
loc STRING COMMENT '部门位置'
)
PARTITIONED BY (day STRING COMMENT '天分区字段')
ROW FORMAT DELIMITED FIELDS TERMINATED BY '\t';
加载分区数据
LOAD DATA [LOCAL] INPATH 'filepath' [OVERWRITE] INTO TABLE tablename [PARTITION (partcol1=val1, partcol2=val2 ...)]
LOAD DATA LOCAL INPATH '/root/dept.txt' INTO TABLE dept_partition PARTITION(day='20260928');
INSERT INTO TABLE tablename [PARTITION (partcol1[=val1], partcol2[=val2] ...)] VALUES values_row [, values_row ...]
INSERT INTO TABLE dept_partition PARTITION(day='20260929') VALUES
(10,'财务部','10005'),
(20,'行政部','10006'),
(30,'法务部','10007');
查询数据
SELECT deptno,
dname,
loc
FROM dept_partition
WHERE day='20260928';
二、分区表的相关操作
1. 查看所有分区信息
SHOW PARTITIONS dept_partition;
2. 增加分区信息
ALTER TABLE table_name ADD [IF NOT EXISTS] PARTITION partition_spec [LOCATION 'location'][, PARTITION partition_spec [LOCATION 'location'], ...];
① 增加单个分区
ALTER TABLE dept_partition ADD PARTITION(day='20260930');
② 增加多个分区(分区之间不能有逗号)
ALTER TABLE dept_partition ADD PARTITION(day='20260928') PARTITION(day='20260929');
3. 删除分区
ALTER TABLE table_name DROP [IF EXISTS] PARTITION partition_spec[, PARTITION partition_spec, ...]
[IGNORE PROTECTION] [PURGE];
① 删除单个分区
ALTER TABLE dept_partition DROP PARTITION (day='20260930');
② 删除多个分区(分区之间必须加逗号)
ALTER TABLE dept_partition DROP PARTITION(day='20260928'), PARTITION(day='20260929');
4. 恢复分区(MSCK 修复表)------了解即可
Hive 将分区表的所有分区信息都保存在了元数据中,只有元数据与 HDFS 上的分区路径一致时,分区表才能正常读写数据。若用户手动创建/删除分区路径,Hive 都是感知不到的,这样就会导致 Hive 的元数据和 HDFS 的分区路径不一致。再比如,若分区表为外部表,用户执行 DROP PARTITION 命令后,分区元数据会被删除,而 HDFS 的分区路径不会被删除,同样会导致 Hive 的元数据和 HDFS 的分区路径不一致。
若出现元数据和 HDFS 路径不一致的情况,可通过如下几种手段进行修复。
修复分区手段:
-
(1)ADD PARTITION 若手动创建 HDFS 的分区路径,Hive 无法识别,可通过
ADD PARTITION命令增加分区元数据信息,从而使元数据和分区路径保持一致。 -
(2)DROP PARTITION 若手动删除 HDFS 的分区路径,Hive 无法识别,可通过
DROP PARTITION命令删除分区元数据信息,从而使元数据和分区路径保持一致。 -
(3)MSCK 若分区元数据和 HDFS 的分区路径不一致,还可使用
MSCK命令进行修复,以下是该命令的用法说明。MSCK REPAIR TABLE table_name [ADD/DROP/SYNC PARTITIONS];
说明:
MSCK REPAIR TABLE table_name ADD PARTITIONS:
-- 会增加 HDFS 路径存在但元数据缺失的分区信息。
MSCK REPAIR TABLE table_name DROP PARTITIONS:
-- 会删除 HDFS 路径已经删除但是元数据信息仍然存储的分区信息。
MSCK REPAIR TABLE table_name SYNC PARTITIONS:
-- 同步 HDFS 路径和元数据分区信息,相当于同时执行以上两条命令。
三、二级分区表
-- 创建二级分区表
CREATE TABLE IF NOT EXISTS dept_partition2(
deptno INT COMMENT '部门编号',
dname STRING COMMENT '部门名称',
loc STRING COMMENT '部门位置'
)
PARTITIONED BY (day STRING COMMENT '一级分区天', hour STRING COMMENT '二级分区小时')
ROW FORMAT DELIMITED FIELDS TERMINATED BY '\t';
-- 加载数据
LOAD DATA LOCAL INPATH '/root/dept.txt' INTO TABLE dept_partition2 PARTITION(day='20260928',hour='15');
LOAD DATA LOCAL INPATH '/root/dept.txt' INTO TABLE dept_partition2 PARTITION(day='20260928',hour='16');
LOAD DATA LOCAL INPATH '/root/dept.txt' INTO TABLE dept_partition2 PARTITION(day='20260929',hour='15');
-- 查询数据
SELECT
*
FROM
dept_partition2
WHERE day='20260928' AND hour='16';
四、动态分区
动态分区设置
-- 开启动态分区功能
SET hive.exec.dynamic.partition=true;
-- 严格模式和非严格模式
-- 动态分区的模式,默认 strict(严格模式),要求必须指定至少一个分区为静态分区,
-- nonstrict(非严格模式)允许所有的分区字段都使用动态分区
SET hive.exec.dynamic.partition.mode=nonstrict;
-- 一条 insert 语句可以同时创建的最大的分区数据,默认 1000 个
SET hive.exec.max.dynamic.partition=1000;
-- 单个 mapper 或者 reducer 可以同时创建的最大分区个数,默认 100 个
SET hive.exec.max.dynamic.partitions.pernode=100;
-- 单个 insert 语句可以创建的最大文件个数,默认 100000
SET hive.exec.max.created.files=100000;
-- 当查询结果为空时且进行动态分区时,是否抛出异常,默认 false
SET hive.error.on.empty.partition=false;
案例
SET hive.exec.dynamic.partition=true;
SET hive.exec.dynamic.partition.mode=nonstrict;
-- 创建学生表
CREATE TABLE IF NOT EXISTS bigdata.students(
id STRING COMMENT '学号',
name STRING COMMENT '姓名',
age INT COMMENT '年龄',
sex STRING COMMENT '性别',
clazz STRING COMMENT '班级'
)
ROW FORMAT DELIMITED FIELDS TERMINATED BY ',';
LOAD DATA LOCAL INPATH '/root/sh_code/student.csv' INTO TABLE students;
-- 创建学生分区表
CREATE TABLE IF NOT EXISTS bigdata.students_partition(
id STRING COMMENT '学号',
name STRING COMMENT '姓名',
age INT COMMENT '年龄',
clazz STRING COMMENT '班级'
)
PARTITIONED BY (sex STRING COMMENT '性别')
ROW FORMAT DELIMITED FIELDS TERMINATED BY ','
LOCATION '/data/bigdata/students_partition';
-- 插入数据
INSERT INTO bigdata.students_partition PARTITION(sex)
SELECT
id,
name,
age,
clazz,
sex
FROM bigdata.students;
-- 查询数据
SELECT * FROM students_partition WHERE sex = '0';
五、总结
本文整理了 Hive 分区表的核心内容,包括:
- 分区表的创建语法与数据加载方式;
- 查看分区、增加分区、删除分区;
- 元数据与 HDFS 分区路径不一致时的修复方式,以及
MSCK REPAIR TABLE的用法; - 二级分区表的创建、加载与查询;
- 动态分区的相关参数设置与完整案例。
掌握这些内容后,可以在 Hive 中更高效地组织大规模数据,并通过分区提升查询性能。