Navicat 17 的异构数据库同步并非真正无缝,必须手动干预字段映射与类型转换,否则易丢数据或报错;需预先创建ENUM类型、配置binlog为ROW模式、处理DEFAULT值;实时同步须启用二进制日志读取并校准位点;同步后须人工核验行数及关键字段一致性。
Navicat 17 自带的「异构数据库同步」功能确实能直接连通 MySQL 和 PostgreSQL,但“无缝”是假象——它不处理类型映射冲突、不自动修正语法差异、也不校验数据一致性。实际用下来,**必须手动干预字段映射和类型转换逻辑,否则大概率丢数据或报错**。
为什么 Navicat 17 的同步任务常卡在「字段类型不匹配」
navicat 内置引擎对 tinyint(1)、datetime、enum、text 等 mysql 类型没有默认 postgresql 映射规则,也不会提示你该选 boolean 还是 smallint。它要么跳过字段,要么硬塞进 text 导致后续查询失败。
-
TINYINT(1)→ 默认映射成INTEGER,但业务中常表示布尔值,应手动改为BOOLEAN -
DATETIME→ PostgreSQL 没有同名类型,需选TIMESTAMP WITHOUT TIME ZONE或带时区版本(取决于 MySQL 时区设置) -
ENUM→ Navicat 不生成CREATE TYPE语句,直接报错“type not exist”,必须提前在 PostgreSQL 手动建枚举类型 -
TEXT→ MySQL 的TEXT最大长度 65535,PostgreSQL 的TEXT虽无限制,但若字段含超长二进制内容(如 Base64 图片),可能触发bytea转换异常
同步前必须手动做的三件事
Navicat 不会主动检查这些,但缺一不可:
- 在 PostgreSQL 中预先创建所有用到的
ENUM类型,名称和值顺序必须与 MySQL 完全一致,例如:CREATE TYPE user_status AS ENUM ('active', 'inactive', 'pending'); - 确认 MySQL 的
binlog_format = ROW且binlog_row_image = FULL(仅实时同步需要;全量同步可略过,但建议统一开启) - 把 MySQL 表中所有
DEFAULT CURRENT_TIMESTAMP改为显式值或删掉,默认值在 PostgreSQL 同步时会被忽略,导致目标端字段为NULL
实时同步任务里最易忽略的配置项
Navicat 17 的「实时同步」依赖 MySQL binlog,但界面藏得深,且默认关闭关键开关:
- 「高级选项」→ 勾选
Enable binary log reading:不勾则只做一次性全量,根本不会监听变更 - 「高级选项」→ 设置
Binlog position:首次运行建议选Latest;若要从历史位点重放,必须填准确的File+Position(用SHOW MASTER STATUS查) - 「字段映射」页签里,每个字段右侧有个小齿轮图标 → 必须点开检查「Target data type」是否被 Navicat 自动改歪了,尤其是
id字段,MySQL 的AUTO_INCREMENT映射后,PostgreSQL 的SERIAL序列值不会自动继承源端最大值,会导致主键冲突
同步完成后一定要验证的两个地方
Navicat 不提供行级比对,所谓「完成」只是任务状态变绿,不代表数据一致:
- 查行数是否一致:
SELECT COUNT(*) FROM mysql_table;vsSELECT COUNT(*) FROM pg_table;—— 若不等,说明某批 INSERT 失败但 Navicat 未报错 - 抽样查时间字段和布尔字段:
SELECT created_at, is_active FROM pg_table LIMIT 5;对比原始 MySQL 数据,常见问题包括:时区偏移未修正、TINYINT(1)被存成0/1字符串而非布尔值











