该错误源于业务逻辑重复插入相同主键,非数据库故障;常见原因包括前端重复提交、定时任务未防重、接口无幂等设计或代码硬编码ID;需查日志、审代码、加监控,并根据冲突ID是否为有效业务数据选择REPLACE/IGNORE/UPDATE策略,或清理脏数据。

先确认是不是业务逻辑在反复插入相同主键
这个错误不是数据库坏了,而是你(或你的代码)正试图把一个已经存在的 id 值再次写进去。最常见的情况是:前端重复提交、定时任务没加防重、接口没做幂等、或者循环里硬编码了 id = 1 这种值。
- 查日志:看报错前后几秒,应用是否连续发了两条一模一样的
INSERT INTO table (id, ...) VALUES (1, ...) - 看代码:重点检查所有显式指定
id的地方,尤其是测试环境手动插数据后忘了删、或导出 SQL 里带了固定id值 - 临时加监控:在插入前加一句
SELECT COUNT(*) FROM table WHERE id = ?,如果返回 >0,说明上游逻辑有问题
别急着删数据,先看冲突值到底有没有业务意义
执行 SELECT * FROM your_table WHERE id = 1;(把 1 换成报错里的具体值)。如果这条记录是正常业务数据(比如用户注册生成的),那问题不在数据库,而在你插入时不该指定 id —— 应该让 AUTO_INCREMENT 自己生成。
- 如果表里已有
id=1,而你又非得插一条新的id=1,那必须明确选择策略:REPLACE INTO(删旧插新)、INSERT IGNORE(跳过不报错)、或ON DUPLICATE KEY UPDATE(只更新字段) - 如果
id=1是脏数据(比如测试残留、迁移错误、脚本误写),再考虑DELETE FROM your_table WHERE id = 1;,但务必先备份整张表 - 注意:
REPLACE INTO会触发DELETE + INSERT,外键关联、触发器、自增计数器都会受影响,不是“安全覆盖”
检查 AUTO_INCREMENT 是否卡住了
有时候表明明设了 AUTO_INCREMENT,但插入时还是报 Duplicate entry '10' for key 'PRIMARY',大概率是自增值没跟上现有最大 id。比如最大 id 是 105,但 AUTO_INCREMENT 还停在 10。
- 查当前设置:
SHOW TABLE STATUS LIKE 'your_table';,看Auto_increment字段值 - 查真实最大值:
SELECT MAX(id) FROM your_table; - 如果前者 ≤ 后者,必须重设:
ALTER TABLE your_table AUTO_INCREMENT = 106;(填比最大值大 1 的数) - 这个值不能随便设小,否则下次插入又撞上已存在
id;也不能设太大,浪费后续 ID 空间
批量导入或迁移时最容易漏掉唯一性校验
用 LOAD DATA INFILE 或 mysqldump 导入数据时,如果源数据本身含重复 id,或目标表 AUTO_INCREMENT 起始值太低,就会批量爆错。
- 导入前先跑一遍:
SELECT id, COUNT(*) FROM your_table GROUP BY id HAVING COUNT(*) > 1;,清掉源数据里的重复 - 导入语句开头加上
SET FOREIGN_KEY_CHECKS = 0; SET UNIQUE_CHECKS = 0;只能绕过约束检查,不能解决根本冲突 - 更稳妥的做法:导入到临时表,用
INSERT IGNORE或ON DUPLICATE KEY UPDATE从临时表往正式表灌,可控性强
真正麻烦的不是报错本身,而是你不知道这条重复的 id 是谁写的、什么时候写的、删了会不会影响其他表——所以每次遇到,第一反应不应该是“怎么跳过”,而是“为什么它会出现”。


















