LIST分区是按离散值列表对表水平拆分的方式,适用于地区编码、状态码等取值有限且不连续的场景;需用PARTITION BY LIST配合VALUES IN定义分区,主键必须包含分区键,且仅支持单列分区。

什么是SQL LIST分区
LIST分区是一种按离散值列表对表进行水平拆分的方式,适用于列值有限、明确且不连续的场景。比如地区编码、状态码、产品类别等字段,取值固定且数量不多,用LIST分区比RANGE或HASH更直观、更易维护。
LIST分区的核心结构与语法要点
LIST分区依赖PARTITION BY LIST子句,必须配合VALUES IN明确指定每个分区包含的具体值。主键或唯一索引必须包含分区键——这是硬性要求,否则建表会失败。
- 分区键只能是单列(多数数据库如MySQL、Oracle支持;PostgreSQL需借助扩展或替代方案)
- 每个值只能归属一个分区,不能重复出现在多个
VALUES IN中 - 所有可能值不必全部覆盖,但未匹配的插入会报错(除非定义
DEFAULT分区) - 分区名建议语义化,例如
p_beijing、p_shanghai,便于后续管理
创建LIST分区表的完整示例(以MySQL 8.0+为例)
假设有一张用户地区分布表,按region_code分区:
CREATE TABLE users_by_region (
id INT NOT NULL,
name VARCHAR(50),
region_code CHAR(2) NOT NULL,
PRIMARY KEY (id, region_code)
)
PARTITION BY LIST (region_code) (
PARTITION p_beijing VALUES IN ('BJ'),
PARTITION p_shanghai VALUES IN ('SH'),
PARTITION p_guangdong VALUES IN ('GD', 'SZ', 'GZ'),
PARTITION p_default VALUES IN (DEFAULT)
);
注意:PRIMARY KEY必须包含region_code(即分区键),否则会提示“A PRIMARY KEY must include all columns in the table's partitioning function”。
日常运维与常见问题处理
LIST分区不像RANGE那样支持自动添加新分区,新增值需手动ALTER TABLE ... ADD PARTITION;删旧值则用DROP PARTITION。操作前务必确认数据归属和业务影响。
- 向已有分区添加新值?不行——
VALUES IN定义后不可修改,只能新建分区或合并再重分 - 如何迁移数据到新分区?用
ALTER TABLE ... REORGANIZE PARTITION(MySQL),将旧分区拆分或合并 - 查询时能自动裁剪分区吗?可以,只要
WHERE region_code = 'SH'条件明确,优化器只扫描p_shanghai - NULL值怎么处理?默认不被任何
VALUES IN匹配,会进DEFAULT分区(如有),否则报错
基本上就这些。LIST分区不复杂但容易忽略约束细节,建表前理清值域、主键设计和默认兜底策略,能省去后期大量调整成本。










