数据库
技术随笔
主键的值重复 Duplicate entry '4294967295' for key 'PRIMARY'
问题现象
ERP 通过商品推送接口向商城推送商品,请求参数如下:
{
"products": [
{
"createTime": "2018-02-07 12:04:07",
"name": "文和测试",
"productCode": "8294967296",
"productId": 8294967296
}
]
}接口返回错误:
Duplicate entry '4294967295' for key 'PRIMARY'
根因分析
商城 product 表(及关联表)的 product_id 字段是 自增 int 类型。int 无符号的最大值是 2^32 - 1 = 4294967295。由于历史数据不断写入,自增 id 已经逼近上限;而 ERP 推送的 productId 是 10 多位(如 8294967296),超过了 int 能表示的范围。MySQL 在插入超范围值时按上限截断,得到的仍是 4294967295,与已有记录主键冲突,于是报“主键的值重复”。
关于 int 的细节
int(11)与int(3)的括号数字只是显示宽度,不影响存储大小和取值范围。- 有符号 int 范围:-2147483648 ~ 2147483647;无符号 int 范围:0 ~ 4294967295。
解决办法:批量改为 bigint
商城中有 50 多张表都包含 product_id 字段,逐张手动修改太慢。用一条 SQL 生成所有 ALTER 语句:
SELECT CONCAT('alter table ', table_name, ' modify ', column_name, ' bigint')
FROM information_schema.columns
WHERE table_schema = 'shop_ceshi' AND column_name = 'product_id';把查询结果复制出来统一执行即可将所有相关字段改为 bigint,字段容量提升到 2^63 - 1,彻底解决溢出问题。