Navicat 同步无主键表会跳过或报错,因其依赖主键或唯一索引做行级比对;无主键时需手动配置复合唯一索引映射、结构同步(仅DDL)、添加业务唯一键、哈希伪主键,或改用原生命令同步。
Navicat 同步无主键表会直接跳过或报错
navicat 数据同步功能默认依赖主键或唯一索引做行级比对。目标表若没有 primary key 或 unique key,它无法判断“某行是否已存在”,结果不是报 duplicate entry 错误,就是静默跳过大量记录——日志显示 “completed”,实际同步行数远低于预期。
常见错误现象:
• 源表 10 万行,目标表只插入几百行
• 日志里没报错,但 SELECT COUNT(*) 明显不对
• 执行后发现所有字段值都是 NULL,或部分列被截断
- 先确认目标表结构:
SHOW CREATE TABLE table_name,检查输出中是否含PRIMARY KEY或UNIQUE KEY - 如果用的是复合唯一索引(如
(user_id, action_type)),必须在 Navicat 的「表映射 → 键映射」中手动勾选这两个字段为匹配依据,否则无效 - 临时补主键不是万能解法:加
ALTER TABLE ADD COLUMN id BIGINT AUTO_INCREMENT PRIMARY KEY FIRST后,历史数据的id值全为 0 或重复,反而引发冲突
无主键表只能靠全字段比对或改用结构同步
Navicat 的「结构同步」不依赖主键,它直接解析 SHOW CREATE TABLE 输出,逐字段比对类型、长度、索引、字符集等元数据。所以如果你只是想让两张无主键表结构一致(比如字段顺序、NOT NULL 属性、默认值),结构同步完全可用。
但注意:
• 字段名必须完全一致,Navicat 不会按语义对齐(比如两个都叫 code 的字段不会自动匹配)
• CHECK 约束、隐藏字段(INVISIBLE)、MySQL 8.0+ 的角色权限定义可能未被识别
• 它不管数据内容,只管 DDL 定义
- 打开「Tools → Structure Synchronization」,选源/目标连接和 schema
- 在预览界面点击某张表 → 底部切换到「Difference」标签页,查看哪些字段类型或属性不一致
- 生成的 SQL 是纯
ALTER TABLE ... MODIFY COLUMN或ADD INDEX,不含任何INSERT语句
真要同步无主键表的数据,得换思路
Navicat 本身不支持无主键表的数据行级同步。所谓“同步”,本质是 INSERT + ON DUPLICATE KEY UPDATE,而这个逻辑必须有唯一标识才能触发。没有主键/唯一索引,就只剩两种现实路径:
-
加唯一业务字段组合:比如
(order_no, item_id)在业务上天然不重复,就在目标表建UNIQUE KEY (order_no, item_id),再在 Navicat「键映射」里指定这两个字段 -
用全字段拼接哈希做伪主键:在源端建视图,加一列
MD5(CONCAT_WS('|', col1, col2, col3)) AS row_hash,目标表也加该字段并建唯一索引,然后映射这个row_hash作为键 -
放弃 Navicat,改用原生命令:比如 MySQL 下导出为 CSV,再用
LOAD DATA INFILE或mysqlimport直接灌入;PostgreSQL 可用psql -c "\copy"。这类方式不校验主键,但也没冲突处理能力
容易被忽略的关键点
很多人试过「仅插入」模式,以为能绕过主键限制,其实不行——Insert only 模式仍需主键或唯一索引来识别重复,否则照样失败。真正起作用的,永远是你手动写的过滤条件(如 created_at > '2026-07-27')和键映射配置,而不是界面上某个开关。
另外,跨库同步时字段类型微小差异(如 MySQL 的 TINYINT(1) 和 PostgreSQL 的 BOOLEAN)会导致 Navicat 认为两行“内容不同”,即使你设了键映射,也可能误判为全量更新。这种问题在无主键表上更难排查。


















