本质是目标库已有同主键或唯一键记录,Navicat默认严格INSERT不跳过不覆盖;需导出SQL手动改为INSERT IGNORE或REPLACE INTO,或启用16+版本的Skip duplicate key errors选项。
Navicat 数据同步/还原时遇到 Duplicate entry 错误,本质是目标库已有同主键或唯一键的记录,而 Navicat 默认走严格 INSERT,不跳过、不覆盖
这个错误不是 Navicat 坏了,而是它在「忠实地执行你选的模式」。默认行为是:遇到重复主键就中断,不自动重试、不智能合并、不提示“要不要覆盖”。你得明确告诉它怎么处理冲突——但注意:REPLACE INTO 和 INSERT IGNORE 在 Navicat 图形界面里**没有直接开关**,必须通过导出 SQL + 手动改写实现。
常见触发场景包括:
- 从测试库还原到开发库,两边都各自插入过 ID=100 的订单
- 多人本地改了同一张配置表,再统一同步到共享环境
- 用 Navicat 导入 Excel 或 CSV 时,源文件含重复业务编码(如
cn字段设了 UNIQUE)
导出 SQL 后手动替换为 INSERT IGNORE 或 REPLACE INTO
这是最可控、最透明的做法。Navicat 的「数据同步」或「导入向导」都支持「导出为 SQL 文件」选项,别跳过这步。
- 勾选「导出为 SQL 文件」,保存后用编辑器打开
- 全局搜索
INSERT INTO `table_name`,替换成INSERT IGNORE INTO `table_name`(跳过冲突) - 若需覆盖旧值(比如以新时间戳为准),则替换成
REPLACE INTO `table_name` - 注意:如果表有自增主键且你用了
REPLACE,ID 可能被重分配,导致后续关联断裂 - 执行前先在目标库跑一遍
SET FOREIGN_KEY_CHECKS = 0;,避免外键校验打断批量执行
为什么不用 Navicat 内置的「Skip duplicate key errors」?
部分版本(尤其 16+)在「仅数据同步」高级选项里确实有这个勾选项,但它等价于加 IGNORE,且只对 INSERT 生效;对 UPDATE 没影响,也不控制外键或触发器行为。
- 它不会帮你处理
ON UPDATE CURRENT_TIMESTAMP字段被强制更新的问题 - 日志里可能只显示「1 warning」,实际没插进去几条,你还得翻同步详情才能发现
- 一旦勾选了,所有重复都静默跳过——如果某条本该报错提醒你数据异常,反而被吞掉了
- Mac 用户连 MySQL 8.0+ 时,还可能因认证插件问题让这个选项失效(需手动勾选
Use MySQL Native Password)
更稳的长期方案:别靠同步工具解决数据一致性
频繁遇到 Duplicate entry,说明同步策略本身有问题。工具只是搬运工,不是仲裁者。
- 明确一个权威源(比如只允许
dev → test单向同步),禁止双向模式——Navicat 的「双向」只是顺序跑两遍单向任务,中间无协调,极易 A 覆盖 B、B 再覆盖 A - 对日志表、统计表、带敏感字段的用户表,建专用视图(如
v_sync_users)再同步,从源头过滤非必要字段 - 主键尽量用
BIGINT AUTO_INCREMENT,避免手动生成 UUID 或业务编码;若必须用字符串主键,确保生成逻辑全局唯一(比如加服务实例前缀) - 上线前跑一次
SELECT id, COUNT(*) FROM t GROUP BY id HAVING COUNT(*) > 1;,确认源数据干净











