You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

MariaDB按月分区:char类型ID+日期列做主键是否可行?

关于MySQL大表按月分区的主键选择方案分析

针对你提到的2000万行interaction表的分区需求,结合MySQL分区规则和文档要求,下面分析两种主键方案的优劣:

方案一:使用id(char(36)) + created_at作为复合主键

可行但存在明显缺陷

  • 不符合文档要求:明确要求主键是「自增ID+日期列」,而当前id是UUID类型的字符串,并非自增整数,直接用它组合created_at会违反文档规范,后续可能带来合规或审计问题。
  • 索引成本高:char(36)的UUID加上datetime类型的created_at,复合主键的长度远大于整数类型,会导致主键索引占用更多磁盘空间,2000万行的情况下,索引体积会比整数主键大几倍,直接影响查询和写入性能。
  • 插入性能差:UUID是无序值,即使组合了created_at,主键索引的排序前缀仍是随机的UUID,插入时会频繁触发索引页的分裂和随机IO,大表批量插入时性能衰减明显,还会加剧索引碎片化。

方案二:新增自增列+created_at作为复合主键

更优且符合规范的选择

  • 满足文档要求:新增的自增整数列(如auto_id,建议用BIGINT避免溢出)+ created_at的组合完全匹配「自增ID+日期列」的主键要求。
  • 性能与存储优势:自增整数(8字节)+ datetime(8字节)的复合主键长度仅为UUID方案的一半左右,主键索引占用空间大幅减少,查询时的IO开销更低,插入时因自增列有序,索引页是顺序写入,碎片化程度极低,大表写入性能更稳定。
  • 分区裁剪效率高:分区键created_at包含在主键中,查询时只要指定created_at范围,MySQL能高效裁剪掉无关分区,配合有序的自增主键,范围查询和索引扫描的效率都会更高。
  • 业务兼容友好:可以保留原id列并设置为唯一索引,业务代码无需大规模修改,依然可以通过原id进行单条记录的查询,只需要在分区相关操作中使用新的复合主键。

实施注意事项

  1. 2000万行的大表修改表结构,禁止直接用ALTER TABLE,建议使用pt-online-schema-change或gh-ost等在线DDL工具,避免锁表影响业务。
  2. 分区策略建议用RANGE分区,基于YEAR(created_at)*100 + MONTH(created_at)的值来划分月度分区,例如:
CREATE TABLE `interaction_new` (
  `auto_id` bigint(20) NOT NULL AUTO_INCREMENT,
  `id` char(36) NOT NULL,
  `tenant_id` int(11) NOT NULL,
  `receiver_user_id` int(11) NOT NULL,
  `sender_user_id` int(11) NOT NULL,
  `type` varchar(50) NOT NULL,
  `created_at` datetime NOT NULL,
  `is_read` tinyint(4) NOT NULL,
  `updated_at` datetime DEFAULT NULL,
  PRIMARY KEY (`auto_id`, `created_at`),
  UNIQUE KEY `uk_id` (`id`),
  KEY `receiver_user_id_index` (`receiver_user_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4
PARTITION BY RANGE (YEAR(created_at)*100 + MONTH(created_at)) (
  PARTITION p202401 VALUES LESS THAN (202402),
  PARTITION p202402 VALUES LESS THAN (202403),
  -- 按需添加历史和未来分区
  PARTITION p_future VALUES LESS THAN MAXVALUE
);

内容的提问来源于stack exchange,提问作者mmac-rio89

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.10 21:50:22