Navicat结构同步默认启用“Drop objects not exist in source”,会静默删除目标库中源库不存在的字段、表、索引等对象,且不二次确认;需人工核对差异列表并取消所有Drop项。
“Drop objects not exist in source”选项被误启用
navicat结构同步默认不会删字段,但只要在同步向导的「选项」页勾选了 drop objects not exist in source,它就会把目标库中源库没有的字段(或表、索引等)全部标记为「待删除」,并生成 drop column 语句。
这个开关默认是开启的——很多人没注意就直接点「部署」,结果生产表里刚加的监控字段被静默删掉。
- 该选项影响所有对象类型:表、字段、索引、外键、视图,不单是字段
- 一旦勾选,Navicat 不会二次确认,也不会检查该字段是否被应用代码引用
- 若源库是开发环境且近期删过字段,而你没做变更评审,这个选项就会把“已下线字段”的删除动作同步到生产
同步前没人工核对差异列表
点击「对比」后,Navicat 会列出所有结构差异,包括 Drop column xxx 这类高危项。但它默认全选,你必须手动取消勾选所有带 Drop 的行。
常见疏漏场景:
- 字段名含下划线或大小写混用(如
user_idvsuserId),Navicat 可能识别为两个不同字段,从而判定目标库字段“多余” - 源库字段被重命名(
ALTER TABLE MODIFY COLUMN old_name → new_name),Navicat 无法识别语义等价,会同时标记Add column new_name和Drop column old_name - 目标库字段是 DBA 手动添加的临时列(如
_sync_flag),不在源库结构里,会被自动纳入删除清单
用了“重建表”模式而非“增量修改”
当 Navicat 检测到字段顺序不一致、字符集冲突或某些类型变更(如 TEXT ↔ MEDIUMTEXT)时,会放弃 ALTER TABLE ... MODIFY COLUMN,转而采用 DROP TABLE + CREATE TABLE 模式。此时,目标表所有字段都会被清空重建,原字段即使未在源库中“消失”,也会因重建逻辑被整体覆盖。
触发重建的典型条件:
- 源库和目标库字段顺序不同(例如源为
id, name, created_at,目标为id, created_at, name) -
Compare collation或Compare auto-increment value被勾选,且实际值不一致 - 目标库表上有 Navicat 未识别的约束(如通过命令行加的 CHECK 约束),导致比对失败后降级为重建
根本原因不是工具缺陷,而是同步逻辑不可逆
Navicat 的结构同步本质是 DDL 差异计算+脚本生成,它不维护“字段生命周期”或“业务上下文”。它只认元数据快照:源库此刻没有这个字段,目标库有 → 就是冗余 → 就该删。
真正容易被忽略的是:这个判断发生在连接建立后的静态比对阶段,不读取任何应用层文档、注释或部署记录。所以哪怕你上周才在生产加了 tenant_id 字段,只要开发库还没合入,它就会被当作“该删对象”。
上线前最有效的防线,永远是人眼扫一遍差异列表里的每一行 Drop 操作,而不是依赖工具“聪明”。


















