1. 什么是分区表?
-
定义:分区表是 Hive 中一种将数据按照指定列(分区列)的值进行分类存储的表。它通过在文件系统(如 HDFS)上创建不同的目录来区分不同分区的数据。
-
核心目的 :
- 优化查询性能 :查询时可以通过
WHERE子句指定分区列的值,Hive 会直接扫描对应的分区目录,而无需扫描整个表的数据,从而大幅提升查询速度。 - 数据管理:便于按业务维度(如日期、地区、部门)对数据进行管理、加载和删除。例如,可以只加载或删除某一天的日志数据。
- 优化查询性能 :查询时可以通过
-
存储结构 :
- 对于表
emp和分区列dept,其在 HDFS 上的目录结构可能如下:
plaintext
/user/hive/warehouse/emp/ ├── dept=Engineering/ │ ├── part-m-00000 │ └── part-m-00001 ├── dept=Sales/ │ └── part-m-00000 └── dept=HR/ └── part-m-00000 - 对于表
创建分区表
关键语法 :partitioned by (column_name data_type)
示例:
sql
create table if not exists emp (
empid string comment '员工ID',
empname string comment '员工姓名',
salary int comment '员工薪资'
)
partitioned by (dept string comment '部门名称') -- 指定分区列
row format delimited
fields terminated by ','
stored as orc;
- 注意 :
- 分区列是虚拟列,它的值并不存储在数据文件中,而是从目录名中推断出来的。
- 一个表可以有多个分区列 (例如
dt string,country string),形成多级分区目录。
向分区表导入数据
向分区表导入数据主要有两种方式:LOAD DATA 和 INSERT ... SELECT。
方法一:使用 LOAD DATA(直接加载文件到指定分区)
sql
-- 加载本地文件到 'engineering' 分区
load data local inpath '/path/to/engineering_emp.txt'
overwrite into table emp
partition (dept='engineering');
-- 加载 HDFS 文件到 'sales' 分区
load data inpath '/path/to/hdfs/sales_emp.txt'
into table emp
partition (dept='sales');
OVERWRITE:覆盖分区内已有的数据。如果想追加数据,去掉此关键字。- Hive 会自动创建
dept=...的目录,并将文件移动或复制到该目录下。
方法二:使用 INSERT ... SELECT(动态分区插入)
当需要从一个已存在的表中读取数据,并根据数据中的某一列动态地创建和填充多个分区时,使用动态分区。
sql
-- 假设源表 emp_staging 包含 dept 列
insert overwrite table emp
partition (dept) -- 只指定分区列名
select empid, empname, salary, dept -- 查询结果的最后一列必须是分区列
from emp_staging;
- 关键点 :
PARTITION (dept): 只列出分区列名,不指定具体值。SELECT语句的最后一列必须是分区列(dept)。Hive 会根据这一列的值自动创建分区。- 通常需要设置参数
set hive.exec.dynamic.partition.mode = nonstrict;来允许全动态分区(默认是strict,要求至少有一个静态分区)。
查询分区表数据
-
查询特定分区的数据(性能最高):
sql
select * from emp where dept = 'engineering'; -
查询多个分区的数据:
sql
select * from emp where dept in ('engineering', 'sales'); -
查询所有分区的数据(等同于查询普通表):
sql
select * from emp; -
查看表的所有分区:
sql
show partitions emp;
5. 修改和删除分区
-
添加一个新的空分区:
sql
alter table emp add partition (dept='finance'); -
删除一个分区(会同时删除该分区对应的目录和数据):
sql
alter table emp drop partition (dept='finance');- 警告:此操作会永久删除数据,请谨慎使用。
总结思维导图
plaintext
Hive 分区表
├── 1. 创建
│ └── create table ... partitioned by (col_name data_type) ...
├── 2. 导入数据
│ ├── a. load data ... into table ... partition (col='value'); (静态分区)
│ └── b. insert overwrite/into ... partition (col) select ...; (动态分区)
│ └── set hive.exec.dynamic.partition.mode = nonstrict;
├── 3. 查询
│ ├── a. select * from table where col = 'value'; (特定分区)
│ ├── b. select * from table where col in ('v1', 'v2'); (多个分区)
│ └── c. show partitions table; (查看所有分区)
├── 4. 管理
│ ├── a. alter table table add partition (col='value'); (添加空分区)
│ └── b. alter table table drop partition (col='value'); (删除分区及数据)
└── 5. 关键考量
├── 优势:查询性能高、数据管理灵活
└── 注意:避免数据倾斜、合理选择分区列、注意小文件问题