Navicat结构同步不对比目标表AUTO_INCREMENT值,仅同步DDL定义;手动修改同步脚本中的AUTO_INCREMENT存在风险;同步后需执行SQL修复自增值;“Include AUTO_INCREMENT value”选项默认开启且不记忆,易导致主键冲突。
Navicat结构同步根本不读取目标表当前自增值
结构同步只比对字段定义、索引、注释、字符集等 ddl 层面的结构信息,auto_increment 计数器属于表元数据(table metadata),不在对比范围内。哪怕目标表已有 10 万条记录、auto_increment 值为 100001,navicat 也完全无视——它只看源表 create table 语句里写的 auto_increment=12345,然后原样写进目标库建表语句或 alter table 操作中。
手动在同步脚本里写 AUTO_INCREMENT=xxx 是危险操作
如果你导出同步脚本后手动补上 AUTO_INCREMENT= 值,实际效果取决于目标表是否存在:
- 目标表不存在:脚本执行
CREATE TABLE ... AUTO_INCREMENT=12345,MySQL 会接受,但这个值仅作为“下一个可用 ID”,不校验是否与已有数据冲突 - 目标表已存在:脚本执行
ALTER TABLE ... AUTO_INCREMENT=12345,MySQL 要求该值必须大于当前最大主键值,否则静默忽略或报错ERROR 1067 (42000): Invalid default value for 'id' - 如果目标表有数据且最大 id 是 999,你硬写
AUTO_INCREMENT=500,MySQL 不会报错但也不生效;写成1000以上才可能成功
同步后想恢复原有自增值,只能靠 SQL 修复
结构同步完成后,必须额外执行一条 SQL 才能真正还原目标表应有的 AUTO_INCREMENT 值:
- 先查目标表当前最大主键:
SELECT COALESCE(MAX(id), 0) FROM table_name - 再设自增起点为最大值 +1:
ALTER TABLE table_name AUTO_INCREMENT = ?(? 替换为上一步结果 +1) - 注意:该语句不能小于等于当前最大主键值,否则被 MySQL 忽略
- 如果目标表为空,
TRUNCATE TABLE table_name更快,它自动重置AUTO_INCREMENT到 1,且不可回滚
最易被忽略的点:高级选项默认开启且不记忆
Include AUTO_INCREMENT value 这个开关默认勾选,每次新建结构同步任务都得手动取消——它不会继承上次设置,也不会按连接/数据库保存偏好。很多人第一次关了,第二次忘了,同步完发现新环境插入就报 Duplicate entry '1' for key 'PRIMARY',然后反复删表重试,其实只是又踩进了同一个坑。











