结构同步只修改数据库结构(ddl),不触碰任何数据;数据同步则更新实际记录(dml),二者操作对象、sql类型及风险完全不同。
navicat 的「结构同步」默认就不动数据,只处理 ddl —— 这是它和「数据同步」功能的根本区别。只要不勾选 compare data,就不可能还原或覆盖任何一行记录。
确认你用的是“结构同步”,不是“数据同步”
两者入口、行为、风险完全不同:
- 结构同步路径:
右键目标数据库 → 结构同步(或工具 → 结构同步),弹窗里明确分「源」和「目标」,生成的全是CREATE TABLE、ALTER TABLE ... ADD COLUMN、DROP INDEX类语句 - 数据同步路径:
工具 → 数据同步,界面顶部写明「Compare data」,会读取行内容、计算哈希、执行INSERT/UPDATE/DELETE,一旦误点且没设好匹配条件,数据真会被改 - 混淆高发场景:Mac 用户常把
Cmd+Shift+S(结构同步)和Cmd+Alt+S(数据同步)按错;Windows 下两个功能都在「工具」菜单第二行,图标相似(齿轮 vs 两个箭头),极易手滑
预览 SQL 时重点盯住三类语句
点击「部署」后必须切到「预览SQL」页签,逐条扫一眼再运行。以下语句出现即需人工判断:
-
DROP COLUMN:字段被删了,但业务代码可能还引用着——不是工具错了,是你得先确认这个字段是否已下线 -
ALTER TABLE ... MODIFY COLUMN ... NOT NULL:目标表若有空值,执行直接报错;得先UPDATE补值或允许 NULL -
DROP FOREIGN KEY+ADD CONSTRAINT成对出现:说明外键名变了,Navicat 没法智能复用旧名,但下游应用若硬编码了外键名(少见但存在),可能出问题
MySQL 8.0+ 同步失败?先检查零日期和版本设置
报错 Invalid default value for 'created_at' 不是 Navicat bug,是它按老规则生成了 DEFAULT '0000-00-00 00:00:00',而 MySQL 8.0 默认启用 NO_ZERO_DATE 模式。
- 同步前务必进「选项 → 高级」,把
MySQL 版本显式设为8.0或更高,Navicat 才会生成CURRENT_TIMESTAMP或NULL - 如果已报错,别重跑同步,直接在预览 SQL 里搜
'0000-,替换成CURRENT_TIMESTAMP(推荐)或删掉整段DEFAULT子句 - 更彻底的解法:源库建表时就别用零日期,Navicat 能正确识别并透传
CURRENT_TIMESTAMP
PostgreSQL 跨 schema 同步容易漏对象
Navicat 默认只对比当前连接用户的 default_schema(通常是 public),其他 schema 如 app、log 下的表、函数、视图压根不会出现在差异列表里。
- 检查连接设置里的
Default Schema是否为你想同步的目标 schema;不是就改,然后重新打开结构同步窗口 - 要同步多个 schema,得分别建两个连接:一个连
source_db?currentSchema=app,另一个连target_db?currentSchema=app,再单独做一次同步 - 函数和视图的
OWNER和GRANT权限不会被同步,得手动补ALTER FUNCTION xxx OWNER TO yyy和GRANT EXECUTE ON FUNCTION xxx TO role_zzz
结构同步真正危险的从来不是“会不会动数据”,而是它太安静——不报错、不提醒、不存档比对快照。每次同步前手动保存配置文件(.ncs),是唯一能回溯“当时为什么没同步某个字段”的方式。别等出了事才翻日志,Ctrl+H 只记执行了什么,不记你关掉了哪个勾选项。











