navicat 默认将 auto_increment 值作为结构属性硬同步,导致目标表自增异常;需在同步向导「高级」选项中手动取消勾选“include auto_increment value”,并同步后手动重置起始值。

Navicat 无法安全同步带有自增主键的表结构差异,不是因为它“不能”,而是它默认把 AUTO_INCREMENT 值当作结构定义的一部分硬同步过去,而这个值在目标表上往往已失效或冲突——同步动作本身能执行,但结果不可用。
AUTO_INCREMENT 被当成 DDL 属性硬写入同步脚本
Navicat 的结构同步逻辑是基于源表的 SHOW CREATE TABLE 输出解析的,其中 AUTO_INCREMENT=12345 被视为和 ENGINE=InnoDB 同等级的“结构属性”,而不是运行时状态。于是生成的脚本里必然包含:
ALTER TABLE `orders` AUTO_INCREMENT = 12345;
这条语句在目标库执行时:
- 若目标表最大
id是999,MySQL 静默忽略(不报错也不生效) - 若最大
id是15000,直接报错ERROR 1067 (42000): Invalid default value for 'id' - 若目标表为空,它就真从
12345开始分配,跳过前 12344 个合法 ID
问题根源不在 Navicat 是否“支持”,而在它默认开启且不记忆的选项:Include AUTO_INCREMENT value
同步向导里关掉 AUTO_INCREMENT 同步的操作路径
这个开关藏得深,每次新建任务都得手动找:
- 进入「结构同步」向导 → 点击「选项」页签
- 点右下角「高级」按钮(不点开就看不到)
- 在弹出面板中找到
AUTO_INCREMENT行 → 取消勾选 - 同理,如果目标表有注释、字符集、存储引擎等差异但你不想动,也在同一位置取消对应项
注意:该设置不保存为全局偏好,也不会按连接/数据库记忆,下次同步仍需重设。
同步后必须手动重置 AUTO_INCREMENT 值
即使关掉了硬同步,Navicat 也不会帮你查目标表当前最大 ID 并设好起点。你得自己补这一步:
- 同步前先查:
SELECT IFNULL(MAX(id), 0) FROM `orders`;
- 同步完成后立刻执行:
ALTER TABLE `orders` AUTO_INCREMENT = ?;
(?替换为上一步结果 + 1)
若目标表确定为空,用 TRUNCATE TABLE <code>orders 更快,它会自动重置自增到 1,且不走 binlog(适合测试环境)。
容易被忽略的底层影响:MySQL 8.0+ 的 innodb_autoinc_lock_mode
即使你完美关掉 AUTO_INCREMENT 同步、也手动设对了起点,MySQL 8.0 默认的 innodb_autoinc_lock_mode = 2(交错模式)仍会让后续插入行为不一致:
- 同一条
INSERT INTO ... SELECT在不同环境生成的 ID 序列可能不同 - 这不是 Navicat 的 bug,但它是你在多环境验证时发现“ID 不连续”“数据顺序对不上”的真实原因
所以跨环境结构同步后,别只盯着是否报错,还要确认业务是否依赖 ID 的连续性或顺序性——若依赖,就得在应用层处理,而非指望数据库保证。











