MySQL 5.7表分区报错:PRIMARY KEY需包含分区函数所有列
逐个分析你的报错问题
1. PRIMARY KEY必须包含分区函数的所有列
MySQL 5.7对分区表有硬性规则:分区键必须是主键或唯一键的组成部分。你应该是用minute_rounded_timestamp作为分区键,但原主键里未包含这个列,违反规则导致报错。
2. 移除主键后,自增列必须定义为键
MySQL要求自增列(比如你的id)必须属于主键或唯一键。移除主键后,自增列没有绑定任何键,触发了这个约束报错。
3. TO_DAYS函数参数数量错误
TO_DAYS()是单参数函数,仅接受一个合法的日期/时间类型值作为参数。你可能在分区函数里写了TO_DAYS(列1, 列2)这类多参数写法,或者传入了非日期类型的列,导致参数错误。
针对性解决方案
结合你的高频查询场景(基于minute_rounded_timestamp),正确的分区表设计应遵循以下步骤:
调整主键,包含分区键
把主键修改为(id, minute_rounded_timestamp)——既满足自增列id属于主键的要求,又让分区键minute_rounded_timestamp成为主键的一部分,符合MySQL 5.7的分区规则。正确使用分区函数
假设minute_rounded_timestamp是DATETIME/TIMESTAMP类型,用时间范围分区的示例代码如下:CREATE TABLE report_table ( id INT AUTO_INCREMENT, minute_rounded_timestamp DATETIME, -- 其他业务列... PRIMARY KEY (id, minute_rounded_timestamp) ) PARTITION BY RANGE (TO_DAYS(minute_rounded_timestamp)) ( PARTITION p20240101 VALUES LESS THAN (TO_DAYS('2024-01-02')), PARTITION p20240102 VALUES LESS THAN (TO_DAYS('2024-01-03')), -- 根据业务需求添加更多分区 );注意:
TO_DAYS()只能传单个日期类型参数;如果minute_rounded_timestamp是INT类型的时间戳,可直接用RANGE分区,或通过FROM_UNIXTIME()转换后再用TO_DAYS()。索引优化建议
分区键已作为主键的一部分,无需单独为其建索引。过多的索引会增加写入开销,反而影响报表表的性能,建议保留高频查询所需的必要索引即可。
内容的提问来源于stack exchange,提问作者Ryan H

