Navicat「仅插入」需目标表有主键或唯一索引,否则无法识别重复而报错或静默跳过;真正增量须在「表映射」设过滤条件(如created_at > '2026-07-26 00:00:00'),并关闭删除和冲突更新选项。
选「仅插入」但目标表必须有主键或唯一索引
navicat 的「仅插入」不是无条件追加,它靠主键或唯一索引判断“是否已存在”。如果目标表没设 primary key 或 unique key,navicat 无法比对,会直接报 duplicate entry 错误,或静默跳过部分行——日志显示 “completed”,实际数据严重缺失。
确认方式:在目标库执行 SHOW CREATE TABLE table_name,输出中必须含 PRIMARY KEY 或明确的 UNIQUE KEY。若用复合唯一索引(如 (user_id, action_type)),需进 Navicat「表映射 → 键映射」手动勾选全部字段作为匹配依据。
常见踩坑点:
- 源表主键是
id(INT),目标表却是id(BIGINT),类型不一致导致匹配失败,所有行都被当新记录插入 - 目标表用 UUID 当主键,源表用自增 ID —— Navicat 找不到匹配字段,
仅插入逻辑完全失效 - 目标表有
NOT NULL字段但没默认值,即使主键不冲突,INSERT 也会因字段为空失败
过滤条件必须写在「表映射」页签的「过滤条件」框里
很多人以为勾了「仅插入」就自动增量,其实不然。Navicat 默认仍全表扫描源数据;不加 WHERE,它会把源库所有行都拉出来逐个比对是否已存在,效率低、易锁表、还可能撞约束。
真正控制“只插新”的,是你手动写的过滤条件,比如:
-
created_at > '2026-07-26 00:00:00'(推荐带秒,避免跨分钟漏数据) -
id > 12345678(仅当id单调递增且不归档/重用时可靠) -
created_at > '2026-07-26 00:00:00' AND status = 'active'(多条件叠加更稳妥)
注意:NOW()、DATE_SUB(NOW(), INTERVAL 1 DAY) 这类函数 GUI 不支持,只认静态字符串;别用 BETWEEN,边界秒级数据容易丢失。
「冲突处理」必须设为「跳过」,且禁用「删除目标中不存在的记录」
即使选了「仅插入」,如果「冲突处理」仍为默认的「停止」,一遇到主键冲突就中断任务;若设为「更新现有记录」,则违背“忽略重复”的前提。
关键操作路径:
- 进「高级选项 → 冲突处理」,明确选
跳过 - 回「Options」页签,务必取消勾选
删除目标中不存在的记录—— 这个选项默认常为启用状态,每次新建任务都要手动关掉,否则同步前先执行DELETE,历史数据会被清空
PostgreSQL / SQL Server 用户注意:它们底层不支持 INSERT IGNORE,Navicat 在「仅插入」下仍走完整流程,高并发时可能因竞态多插一次,得靠上游业务层控频或加应用锁。
预览 SQL 是唯一验证手段
别信界面上的勾选和描述,最终行为由生成的 SQL 决定。点「Compare & Preview」后,切换到底部「SQL」标签页,逐条检查:
- 每条
INSERT INTO是否含IGNORE或类似语义(MySQL 下对应INSERT IGNORE,其他数据库表现不同) - 是否有意外出现的
UPDATE或DELETE语句(说明某处误启了相关选项) - 敏感字段(如
password)是否真的没出现在VALUES或SET子句中
最常被忽略的一点:时间字段的时区。源库用 UTC,Navicat 客户端设为 CST?那 created_at > NOW() - INTERVAL 1 DAY 会漏掉 8 小时数据——但你根本看不到这个错误,因为 SQL 预览里只显示静态字符串,不反映运行时计算逻辑。


















