INT / BIGINT) 的场景,如用户 ID、纯数字订单号。BLOB / TEXT 外的多种数据类型,系统使用内部哈希函数处理数据。VARCHAR / CHAR) 的场景,如 UUID、身份证号、业务流水号。DROP PARTITION 秒级删除过期的历史数据。CREATE TABLE `mall`.`orders` (`order_id` bigint NOT NULL,`user_id` bigint NOT NULL,`amount` decimal(10,2),`create_time` datetime DEFAULT CURRENT_TIMESTAMP,-- 主键必须包含分区键PRIMARY KEY (`order_id`))PARTITION BY HASH(`order_id`)PARTITIONS 64;
CREATE TABLE `user_center`.`user_profiles` (`user_uuid` varchar(36) NOT NULL,`nick_name` varchar(50),`register_time` datetime,PRIMARY KEY (`user_uuid`))PARTITION BY KEY(`user_uuid`)PARTITIONS 64;
RANGE、RANGE COLUMNS、LIST、LIST COLUMNS、HASH、KEY。CREATE TABLE `sys`.`audit_logs` (`log_id` bigint NOT NULL,`content` text,`log_time` datetime NOT NULL,PRIMARY KEY (`log_id`, `log_time`))PARTITION BY RANGE COLUMNS(`log_time`) (PARTITION p202601 VALUES LESS THAN ('2026-02-01'),PARTITION p202602 VALUES LESS THAN ('2026-03-01'),PARTITION p202603 VALUES LESS THAN ('2026-04-01'));
PARTITION p_future VALUES LESS THAN (MAXVALUE) 作为兜底分区。MAXVALUE 是静态兜底分区,不会随时间自动按月分裂。一旦写入超出最后一个分区上界的数据,所有新数据会持续落入 p_future,导致:p_future 无限膨胀,失去按月清理的能力;ADD PARTITION p202304,会因 MAXVALUE 已占据末尾而直接报错,必须先 REORGANIZE PARTITION p_future,操作复杂且代价高。ADD PARTITION 预创建下一个月分区。操作场景 | SQL 示例 | 说明 |
删除过期分区 | ALTER TABLE sys.audit_logs DROP PARTITION p202601; | 秒级清理过期数据,性能远优于 DELETE |
清空分区数据 | ALTER TABLE sys.audit_logs TRUNCATE PARTITION p202601; | 保留分区结构,仅清空数据 |
预创建下月分区 | ALTER TABLE sys.audit_logs ADD PARTITION (PARTITION p202604 VALUES LESS THAN ('2026-05-01')); | 仅可在末尾新增,值必须严格递增 |
拆分 MAXVALUE 分区 | ALTER TABLE sys.audit_logs REORGANIZE PARTITION p_future INTO (PARTITION p202603 VALUES LESS THAN ('2026-04-01'), PARTITION p_future VALUES LESS THAN (MAXVALUE)); | 误用 MAXVALUE 后的补救手段 |
查看分区列表 | SELECT PARTITION_NAME, PARTITION_DESCRIPTION, TABLE_ROWS FROM information_schema.PARTITIONS WHERE TABLE_SCHEMA='sys' AND TABLE_NAME='audit_logs'; | 查询当前分区状态与数据量 |
环节 | 推荐方案 | 说明 |
未来分区预创建 | 通过外部调度任务执行 ALTER TABLE ... ADD PARTITION | 系统不会自动按时间扩展分区,必须由外部周期性触发 |
CREATE TABLE `crm`.`customers` (`cust_id` bigint NOT NULL,`city_id` int NOT NULL,`name` varchar(50),PRIMARY KEY (`cust_id`, `city_id`))PARTITION BY LIST(`city_id`) (PARTITION p_bj VALUES IN (10),PARTITION p_sh VALUES IN (20),PARTITION p_others VALUES IN (30));
CREATE TABLE `sys`.`massive_logs` (log_id bigint NOT NULL,user_id bigint NOT NULL,content text,log_time datetime NOT NULL,PRIMARY KEY (log_id, log_time, user_id))PARTITION BY RANGE COLUMNS(log_time)SUBPARTITION BY HASH(user_id)SUBPARTITIONS 4(PARTITION p202601 VALUES LESS THAN ('2026-02-01'),PARTITION p202602 VALUES LESS THAN ('2026-03-01'),PARTITION p202603 VALUES LESS THAN ('2026-04-01'));
-- 错误:分区键 user_id 没有包含在主键中CREATE TABLE `error_table` (`id` bigint NOT NULL PRIMARY KEY,`user_id` bigint NOT NULL) PARTITION BY HASH(`user_id`);
-- 正确:将 user_id 加入联合主键CREATE TABLE `correct_table` (`id` bigint NOT NULL,`user_id` bigint NOT NULL,PRIMARY KEY (`id`, `user_id`)) PARTITION BY HASH(`user_id`);
UPDATE 语句修改分区键的值,这可能会导致数据行在物理节点间迁移(DELETE + INSERT),代价较高。WHERE 子句中带上分区键(如 WHERE user_id = ?),TDSQL Boundless 可以直接路由到特定节点,性能极高。PARTITION BY HASH(col1 + col2) 或 KEY(col1, col2)。但这会增加复杂性,通常建议使用单一的高基数列作为分区键。MAXVALUE 兜底,下个月会自动建分区吗?MAXVALUE 是静态兜底分区,新数据只会落入该分区,不会自动按月分裂。TDSQL Boundless 系统暂不支持自动预创建未来分区,需要通过外部调度任务定期执行 ALTER TABLE ... ADD PARTITION 来预创建下一个时间段的分区。ALTER TABLE ... REMOVE PARTITIONING 移除分区后重新定义,或者直接 ALTER TABLE ... PARTITION BY RANGE COLUMNS(...) (...) 重建分区策略。注意:重建分区会涉及数据重组,大表请评估代价并选择业务低峰期执行。MAXVALUE 兜底分区,写入会报错 ER_NO_PARTITION_FOR_GIVEN_VALUE,提示 “Table has no partition for value xxx”。这是预期行为,可以作为 “忘记预创建分区”的兜底告警信号,避免数据静默落入 MAXVALUE 分区造成后续清理困难。文档反馈