Na vicat Cloud 弹窗里那个“conflict detected”,根本不是文件系统层面的冲突——它压根没在同步文件,而是在校验数据库表里的记录版本。简单说,就是本地和云端对同一张表里、同一个主键(或唯一键)值的记录,各自都动过手,系统就判定为冲突。所谓“保留本地”或“保留云端”,本质上是单向覆盖整行,不会帮你合并字段。

为什么 Na vicat Cloud 不告诉你哪一行、哪个字段冲突
很多人第一次遇到这个提示时,第一反应是:到底哪一行有问题?具体改了哪个字段?对不起,它不回答这个问题。机制上,Na vicat Cloud 不会逐字段比对,只比对一条变更摘要加上时间戳。举个例子,本地和云端都对 users 表里 id = 123 的记录执行了UPDATE,哪怕本地只改了 email,云端只改了 phone,系统照样判定为冲突,然后弹窗只丢给你一句“conflict detected”,至于到底哪个字段是冲突根源,你得自己猜。
- 后台用的是乐观锁:每条记录带一个隐式版本号(不是表里的真实字段),修改时校验这个版本号是否没变过
Compare with Cloud这个功能,仅对 MySQL 和 PostgreSQL 开放;SQLite 用户直接没得用,连对比入口都不显示- 冲突提示出现后,
Cloud Sync Status里的Local version和Cloud version数字会变得不一致,但不会标出差异到底在哪张表——你得手动点开每张带 ⚠️ 图标的表,一个个去翻才能定位
选 “Use Local” 后发现云端改的字段没了,是 bug 吗
不是 bug,是设计如此。Na vicat Cloud 的 merge 逻辑是整行覆盖,不是字段级合并。比如云端把 status 改成了 'shipped',本地把 updated_at 改成了当前时间,你选了 Use Local,结果就是 status 直接被打回旧值,云端改的内容全部丢失。
- 导出前,务必右键表 →
Export Wizard,格式选SQL,勾选Only INSERT/UPDATE statements,先看清楚本地到底改了哪些数据 - 再连上云库,执行
SELECT * FROM users WHERE id = 123,确认云端当前值是什么 - 如果必须同时保留双方的修改,单靠界面是做不到的。得切到 SQL 模式,用
SELECT ... FOR UPDATE锁住行,手写UPDATE合并逻辑,再触发同步 merge操作一旦执行不可撤回,而且不会触发外键级联或触发器——这一点极容易被忽略,后果可能很严重
多人协作时,为什么总在同一张表反复冲突
因为 Na vicat Cloud 的同步粒度实际上是整张表,而不是某几行。只要有人提交了 orders 表里任意一行的变更,其他人再编辑该表里其他任何行,哪怕改的是完全不重叠的数据,下次同步时照样会触发冲突检查。
- 高频更新的大表,建议按业务域拆分:比如
orders_2024_q1、orders_2024_q2,用视图统一查询,物理隔离之后能有效降低冲突概率 - 禁用自动同步:
Settings → Cloud → Auto-sync on sa ve取消勾选,改用na vicat-cli --sync配合定时任务来控制节奏 - 团队内部最好约定一个“编辑窗口期”:比如每天 10:15–10:30 统一提交,其余时间只读,避免零散修改叠加起来触发校验
说实话,真正的麻烦不是选“本地”还是“云端”,而是默认机制既不暴露冲突细节,也不支持字段级合并,更不记录谁在什么时候改了哪一行。这些短板都得靠外部手段补上,比如用 Git 管理 DDL 变更脚本,或者在应用层加审计字段来追踪。
