Navicat结构同步默认仅对空表比对字段DEFAULT值,非空表会跳过该比对;需手动进入Compare Options关闭“Ignore column default value”才能强制比对,默认值差异须通过DDL面板确认。
结构同步默认不比非空表的字段默认值
navicat 的结构同步功能在对比字段默认值时,**只对空表严格比对**;只要表里有任意一行数据,它就会跳过 default 值比较——这不是 bug,是它的设计逻辑。你看到“无差异”,很可能只是它根本没比,默认值不同也不会标红。
常见现象:源库字段是 VARCHAR(255) DEFAULT 'N',目标库是 VARCHAR(255) DEFAULT NULL,但结构比对界面显示“一致”。只有当你手动导出 DDL 或用 SHOW CREATE TABLE 对比,才会发现差异。
- 必须确保两张表都为空,
DEFAULT才会参与比对(极少适用) - 若表已上线、有历史数据,这条路走不通
- Navicat for MySQL 16+ 仍沿用该逻辑,未修复
用 Compare Options 手动启用默认值比对
即使表非空,也能强制 Navicat 比对默认值,但得关掉一个默认开启的开关:Ignore column default value。这个选项藏在结构同步窗口的「Compare Options」里,不是同步设置,也不是全局偏好。
操作路径:工具 → 结构同步 → 选好源/目标库 → 点右下角 Options → 进入 Compare Options → 取消勾选 Ignore column default value → 点击 重新对比。
- 勾选状态默认为 on,必须手动关闭
- 关闭后,
DEFAULT ''和DEFAULT NULL会被识别为差异 - 注意:如果字段类型不兼容(如
TINYINTvsENUM),默认值比对可能被跳过,优先检查类型一致性
DDL 面板才是默认值差异的最终确认入口
界面上标红了“字段定义不同”,但你不确定是不是默认值惹的祸?别信概览行,右键那条差异 → 选 在 DDL 比较中查看。这里会并排显示源库和目标库的完整字段定义,DEFAULT 子句是否一致一目了然。
例如:
col_status VARCHAR(10) DEFAULT 'active' ← 源库 col_status VARCHAR(10) DEFAULT NULL ← 目标库
这种差异只有在 DDL 面板里才能 100% 确认,而且能避免把 NOT NULL 变化或字符集变化误判成默认值问题。
- DDL 面板不自动刷新,每次修改 Compare Options 后必须点“重新对比”
- 如果字段用了函数默认值(如
DEFAULT CURRENT_TIMESTAMP),Navicat 会比对字面量,不解析语义,CURRENT_TIMESTAMP和NOW()视为不同 - MySQL 8.0+ 的表达式默认值(如
DEFAULT (UPPER(name)))必须完全一致,空格、括号位置差一点都会标为差异
真正麻烦的是默认值 + NOT NULL 组合变更
当你改一个字段从 DEFAULT NULL → DEFAULT '' NOT NULL,Navicat 会生成两条语句:ALTER COLUMN ... SET DEFAULT '' 和 MODIFY COLUMN ... NOT NULL。但执行顺序错位或目标表有存量 NULL 值时,第二条会失败。
这不是比对问题,而是同步脚本生成逻辑的盲区——Navicat 不校验变更依赖关系,也不预检存量数据。
- 同步前务必手动查:目标表该字段是否存在
IS NULL记录 - 如有,先执行
UPDATE table SET col = '' WHERE col IS NULL - DDL 面板里看到
DEFAULT和NOT NULL同时变,就得警惕这两步是否可原子执行
默认值差异本身不难比,难的是它常和约束、存量数据、执行顺序缠在一起,而 Navicat 从不在界面上提醒你这些。











