主键冲突非Navicat bug,而是因Key Mapping未正确勾选主键/唯一键导致全量INSERT撞约束;解决关键在于准确配置映射、版本≥15启用Skip duplicate key errors,或导出SQL替换为INSERT IGNORE/REPLACE INTO。

主键冲突(Duplicate entry for key 'PRIMARY')不是 Navicat 的 bug,而是它严格按你配置的逻辑执行 INSERT 时撞上了 MySQL 的约束——解决的关键不在“绕过错误”,而在控制“何时 INSERT、何时 UPDATE、是否跳过”。
Key Mapping 必须对齐主键或唯一键
勾选了 Update records 却仍报主键冲突,90% 是这里出错。Navicat 不会自动识别主键,它只认你在 Step 2 的 Key Mapping 页面里手动勾选的字段。
- 单主键表:必须显式勾选
id(或实际主键列名),不能依赖“同名自动映射” - 复合主键表:
order_id和item_seq都得勾上,漏一个,整张表就退化为全量INSERT INTO - 预览时切到 Difference 标签页,若看到某行标为
Insert,但目标库查SELECT * FROM t WHERE id = XXX已存在,说明 Key Mapping 错了,或两边id类型不一致(如源是BIGINT,目标是INT)
Skip duplicate key errors 仅在 Navicat 15+ 的「错误处理」页生效
这个选项是静默跳过 ERROR 1062 的唯一直接开关,但它藏得深、限制多,旧版本根本没这功能。
- 位置:同步向导 →
Options→Error Handling→ 勾选Skip duplicate key errors - Navicat 12/14 等旧版本没有该选项,勾选无效;菜单
Help → About确认版本 ≥ 15 再操作 - 它只影响
INSERT语句,对UPDATE或DELETE冲突无作用;若日志里报的是UPDATE报错,说明 Key Mapping 没设对,不是这个选项能解决的 - 启用后冲突行只记 warning,不中断后续,但日志里不会列出具体跳过了哪些值,容易漏审
导出 SQL 后手动替换 INSERT 是最可控的方式
比起依赖图形界面开关,导出脚本再编辑,能看清每条语句、控制覆盖逻辑、规避外键中断,适合生产环境。
- 同步向导最后一步务必勾选
Generate synchronization SQL script并指定路径 - 打开 .sql 文件,全局查找
INSERT INTO `table_name`,替换成INSERT IGNORE INTO `table_name`(跳过冲突)或REPLACE INTO `table_name`(先删后插) -
REPLACE INTO会重置自增 ID、触发ON DELETE行为、清空ON UPDATE CURRENT_TIMESTAMP字段,慎用 - 执行前加
SET FOREIGN_KEY_CHECKS = 0;,执行完补SET FOREIGN_KEY_CHECKS = 1;
结构同步误触发主键冲突?先确认你真在做结构同步
结构同步(Schema Sync)本身不生成 INSERT,报 Duplicate entry 说明你无意中启用了数据同步。
- 检查 Step 1 的
Options页是否勾选了Synchronize data—— 勾了就是数据同步,不是结构同步 - 点
Preview后看 SQL 预览,只要出现INSERT INTO或REPLACE INTO,就不是纯结构变更 - 结构同步里没有
Skip duplicate key errors开关,这个选项只存在于数据同步流程的「错误处理」页 - 如果目标表已有数据,又在结构同步时误勾了
Truncate before insert,那本质还是数据操作,不是结构问题
真正容易被忽略的点是:Navicat 对主键的判断完全静态,不感知数据分布;它不会因为目标表 MAX(id) 是 100000 就自动把下一条 INSERT 的 id 改成 100001 —— 它只忠实地执行你配置的映射逻辑和 SQL 模式。所以每次同步前,先查 SELECT IFNULL(MAX(id), 0) FROM table_name,比事后修数据省力得多。











