Navicat数据同步需手动建目标表并确保字段兼容,逐表配置映射规则,依赖主键/唯一索引实现更新,不支持自动增量同步,适合一次性或低频任务。
同步前必须确认目标表结构是否兼容源表字段
navicat 的「数据同步」功能不会自动创建目标表,也不会智能适配字段类型或长度。如果你试图把 orders、customers、products 三张结构差异大的表同步进一张 unified_log 表,navicat 会在映射阶段报错:column 'xxx' does not exist in target table 或 data truncation: data too long for column。
实操建议:
- 先手动建好目标表
unified_log,确保它包含所有源表中你打算映射的字段(如source_table_name、record_id、created_at、json_payload等),并预留足够长度(比如用TEXT存序列化行数据) - 字段名不必和源表一致,但类型要能容纳源值——例如源表
user_id是BIGINT,目标列就不能是INT - 如果要用
INSERT IGNORE或REPLACE避免主键冲突,目标表必须有明确的主键或唯一索引
用「同步映射」自定义每张源表的字段投射规则
Navicat 同步界面里的「映射」不是全局配置,而是按源表逐个设置。点击某张源表右侧的 Map 按钮后,你能为每一列指定:填入目标表哪一列、是否常量值、是否忽略、是否用表达式生成(如 CONCAT('orders-', id))。
常见场景与要点:
- 想标记数据来源:给所有源表都映射一个固定值到目标表的
source_table_name字段,比如'orders'(注意加单引号,否则 Navicat 当列名处理) - 时间字段对齐:源表用
order_time,另一张用created_on,统一映射到目标表的event_time即可 - 避免 NULL 冲突:若目标列定义为
NOT NULL,而源值可能为空,可在映射里写表达式如IFNULL(phone, '')(MySQL)或COALESCE(phone, '') - 不支持跨表关联映射——不能在映射里写
(SELECT name FROM customers WHERE id = orders.customer_id),那得先在源端做视图或临时表
同步执行时要注意「操作类型」和「冲突处理」的实际行为
Navicat 数据同步默认是 INSERT,但勾选「Update existing records」后,它实际执行的是 INSERT ... ON DUPLICATE KEY UPDATE(MySQL)或 MERGE(PostgreSQL/SQL Server)。这个逻辑完全依赖目标表的主键或唯一约束。
容易踩的坑:
- 没设主键/唯一索引 → 勾了更新也无效,只会不断重复插入
- 主键由多个字段组成 → 必须确保所有主键字段都在映射列表中,且值能被正确传递,否则可能误判为“新记录”
- 使用
REPLACE INTO模式时,会先删后插,触发器和外键级联动作会被激活,线上环境慎用 - 同步中途失败,不会自动回滚已执行的部分——多表同步建议分批执行,或提前备份目标表
增量同步没法靠一次配置长期运行
Navicat 的同步任务本身不保存「上次同步时间点」或「最大 ID」这类状态,每次都是全量比对(除非你在 SQL 过滤条件里手动加 WHERE updated_at > '2024-06-01')。这意味着:你想每天同步新增订单,就得每天改一次过滤条件,或者把时间阈值写成变量(但 Navicat 不支持变量替换)。
可行替代方案:
- 在源表加
is_synced TINYINT DEFAULT 0字段,同步成功后用UPDATE批量置 1,并在下次同步过滤WHERE is_synced = 0 - 用 Navicat 的「计划任务」+ 自定义 SQL 脚本组合:先查出最大
id记入日志表,再用该值作为下次同步的WHERE id > ?条件 - 真正需要稳定增量,应转向数据库原生机制(如 MySQL binlog + canal)或 ETL 工具(DataX、Airbyte),Navicat 更适合一次性或低频汇总
映射逻辑越复杂,越要先在小数据集上验证结果——比如只同步 10 条,导出目标表检查字段是否错位、NULL 处理是否符合预期。一旦字段映射错位,Navicat 不会警告,只会静默把 A 列值写进 B 列。


















