duplicate entry for key 'primary' 错误表明navicat正执行insert且目标表已存在相同主键记录,属数据同步冲突;勾选update records仍报错,主因key mapping未正确设置为主键或唯一键字段,导致navicat误判所有行为“不存在”而全量insert;真正跳过冲突需在options→error handling中启用skip duplicate key errors(仅navicat 15+支持),或导出sql后手动将insert into替换为insert ignore into。
duplicate entry for key 'primary' 错误说明 navicat 正在执行 insert,且目标表已存在相同主键值的记录——这不是结构同步问题,而是数据同步阶段的明确冲突信号。
为什么勾选了 Update records 还报主键冲突
Navicat 判断“是否该更新”完全依赖 Key Mapping 设置。如果映射字段不是主键(比如只选了 name),它就会把所有行都当成“目标不存在”,全部走 INSERT INTO,自然触发 Duplicate entry。
- 进入同步向导 Step 2 的
Key Mapping页面,手动确认每张表的匹配字段是主键列(如id)或业务唯一键(如order_no) - 复合主键必须全部字段勾选为 Key;漏一个,比对就失效
- 预览时点击某张表 → 底部切到
Difference标签页 → 查看被标为Insert的行:若id值已在目标库存在,说明Key Mapping错了,或两边id类型不一致(INTvsBIGINT)
同步向导里怎么真正跳过冲突行
Skip duplicate key errors 是唯一能静默跳过 ERROR 1062 的开关,但它藏在「Options」→「Error Handling」页,且仅 Navicat 15+ 支持。
- 旧版本没有这个选项,必须导出 SQL 后手动替换
INSERT INTO为INSERT IGNORE INTO - 勾选后,冲突行只记 warning,不中断后续同步;但日志里不会告诉你跳过了哪几条,容易漏审
- 它只对
INSERT生效,不影响UPDATE或DELETE行为
导出 SQL 后怎么安全改插入逻辑
直接启用 Skip duplicate key errors 看似省事,但会掩盖数据状态差异。更可控的做法是导出脚本后人工干预。
- 同步向导最后一步勾选
Generate synchronization SQL script并指定路径 - 打开生成的
.sql文件,全局查找INSERT INTO `table_name`,替换为INSERT IGNORE INTO `table_name` - 若需覆盖(而非跳过),改用
REPLACE INTO,但注意:它会先DELETE再INSERT,可能重置updated_at、触发外键级联或丢失自增 ID - 改完后不要直接双击运行,用命令行
mysql -u user -p db_name 执行,方便加 <code>-v查看详细输出
最容易被忽略的底层陷阱
很多主键冲突其实和 Navicat 无关,而是 MySQL 自身行为在同步过程中被放大。
- 目标表
AUTO_INCREMENT被结构同步重置为源表当前值(比如从 100000 变成 500),后续INSERT必然撞上已有主键——必须在结构同步「Advanced」页取消勾选AUTO_INCREMENT - 即使没同步结构,只要目标表有唯一索引,插入失败时 MySQL 仍会自增 ID,造成逻辑断层,这无法靠 Navicat 设置规避
-
INSERT IGNORE和REPLACE INTO都不触发ON UPDATE CASCADE,如果表定义了级联更新,实际效果和预期可能不一致











