根本原因是Navicat默认将源库AUTO_INCREMENT值硬编码进建表语句并覆盖目标表起点,导致新插入撞上已有主键;需导出时关闭“包含AUTO_INCREMENT值”选项,并同步后执行ALTER TABLE AUTO_INCREMENT = MAX(id)+1对齐。

跨系统迁移时主键自增步长冲突,根本不是步长(AUTO_INCREMENT 增量值)本身的问题,而是 Navicat 默认把源库的 AUTO_INCREMENT 当前值硬编码进建表语句,直接覆盖目标表的自增起点——哪怕目标表已有 10 万条数据,它也强行设成 51110,下一条插入就撞上重复主键。
导出结构时必须关掉「包含 AUTO_INCREMENT 值」
这个选项默认开启,且每次新建任务都重置,不记忆、不继承。不手动关,等于主动埋雷。
- 右键表 →「转储 SQL 文件」→「高级」选项卡 → 取消勾选
Include AUTO_INCREMENT value(中文版叫「包含 AUTO_INCREMENT 值」) - 结构同步向导中:Step 1 →「选项」→「高级」→ 找到
AUTO_INCREMENT行 → 确保复选框未勾选 - 验证是否生效:勾选
Generate SQL only (do not execute),打开预览 SQL,搜索AUTO_INCREMENT=;若仍存在,说明没关对位置
跨平台同步后必须重置 AUTO_INCREMENT 起点
即使关了导出选项,目标库若已存在数据,新插入仍可能冲突——因为 MySQL 不会自动把 AUTO_INCREMENT 设为 MAX(id) + 1,它只认你显式写的值或上次插入后的内部计数器。
- 同步完成后立即执行:
SELECT COALESCE(MAX(id), 0) FROM your_table; - 再执行:
ALTER TABLE your_table AUTO_INCREMENT = ;(例如ALTER TABLE users AUTO_INCREMENT = 100001;) - 注意:
ALTER TABLE ... AUTO_INCREMENT = 1在非空表上静默无效;必须大于当前最大值才生效
MySQL 8.0+ 的 innodb_autoinc_lock_mode 影响不可忽略
即使你关了 AUTO_INCREMENT 同步、也重置了起点,批量插入时 ID 序列仍可能在不同环境不一致——这不是 Navicat 的问题,而是 MySQL 自身行为。
- MySQL 8.0 默认
innodb_autoinc_lock_mode = 2(interleaved 模式),允许多个 INSERT 并发分配 ID,顺序不保证 - 同一份 SQL,在 macOS 本地和 Linux 测试库执行,生成的 ID 可能完全不同
- 若业务依赖 ID 严格递增(如分页、排序),不能只靠 Navicat 设置,得在应用层用事务+
SELECT LAST_INSERT_ID()或改用 UUID
最易被忽略的一点:Navicat 从不校验目标表实际数据状态,它只按脚本执行。所谓“规避”,本质是两件事——导出时不写死起点,导入后立刻对齐起点。中间任何一环漏掉,冲突就只是时间问题。


















