跨异构数据库迁移应首选data transfer模式,单向一次性迁移结构与数据;避免使用data synchronization,因其依赖主键且类型兼容性差;需手动处理类型映射、ddl兼容性、编码及扩展依赖等问题。
navicat 里怎么选对数据迁移类型
跨异构数据库迁移(比如 MySQL → PostgreSQL 或 SQL Server → Oracle)不是点“开始”就能跑通的,Navicat 会强制你选迁移类型:Data Transfer 和 Data Synchronization 容易混淆,但本质不同。Data Transfer 是单向、一次性搬数据(含结构+数据),适合初始化迁移;Data Synchronization 是双向比对+增量更新,依赖主键/唯一约束,跨库时极易失败——尤其当源目标字段类型不兼容(如 MySQL 的 TEXT 对 PostgreSQL 的 TEXT 看似一样,但长度语义不同)。
实操建议:
- 首次迁移一律用
Data Transfer,勾选Transfer structure and data - 别开
Compare data或Synchronize data,这些在异构场景下基本不可靠 - 如果目标库已有表结构,先手动删掉或勾选
Drop tables if exist(注意备份!) - MySQL 到 PostgreSQL 时,Navicat 默认把
TINYINT(1)映射成BOOLEAN,但 PostgreSQL 的BOOLEAN不接受2或NULL,得提前在字段映射里改成SMALLINT
字段类型自动映射为什么总出错
Navicat 的类型映射表是静态预设的,不读取目标库实际版本能力。比如它把 SQL Server 的 DATETIME2 固定转成 PostgreSQL 的 TIMESTAMP WITH TIME ZONE,但如果你的目标 PostgreSQL 版本低于 10,这个类型就不支持,迁移直接卡在建表阶段,报错信息是:ERROR: type "timestamp with time zone" does not exist。
常见陷阱:
- Oracle 的
NUMBER(10,0)被映射成 PostgreSQL 的INTEGER,但源数据实际存了超 2147483647 的值,迁移后溢出变负数 - MySQL 的
VARCHAR(255)在 Navicat 里默认对应 PostgreSQL 的CHARACTER VARYING(255),没问题;但若源字段含 emoji,MySQL 用utf8mb4,PostgreSQL 需确保client_encoding = 'UTF8',否则乱码不报错,只丢字符 - SQL Server 的
UNIQUEIDENTIFIER被映射成 PostgreSQL 的UUID,但目标库没装uuid-ossp扩展,建表就失败
怎么绕过 Navicat 的 SQL 生成限制
Navicat 迁移过程中会自动生成建表 SQL,但它不支持某些异构语法转换:比如 MySQL 的 ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 会被整个忽略,而 PostgreSQL 的 CREATE TABLE ... WITH (fillfactor=80) 它压根不生成。更麻烦的是,它无法处理源库的自定义函数、存储过程、触发器——这些全被跳过,且不提示。
稳妥做法:
- 先导出源库 DDL(用 Navicat 的
Database > Dump SQL File),再用文本工具批量替换关键字(如ENGINE=InnoDB→ 删除,AUTO_INCREMENT→SERIAL) - 把清理后的 DDL 手动执行到目标库,再用 Navicat 做纯数据迁移(取消勾选
Transfer structure) - 对含计算列、生成列的表(如 MySQL 5.7+ 的
GENERATED ALWAYS AS),必须先在目标库建好等效视图或冗余字段,否则Data Transfer会跳过整张表 - 迁移前检查 Navicat 日志窗口(
View > Log),重点看[DDL]和[Data]分段输出,别只盯着进度条
连接超时和大表迁移卡死怎么办
Navicat 默认连接超时是 30 秒,而跨库迁移时,建索引、约束或大批量 INSERT 可能卡住十几分钟。现象是界面假死、日志停在某张表、任务状态变成 Running (no response),但后台 PostgreSQL/MySQL 其实还在干活。
关键参数要调:
- 在连接设置里,把
Connection timeout改成300(秒),Query timeout改成0(禁用) - 大表迁移前,在目标库手动关掉 autocommit:
SET AUTOCOMMIT = OFF;(PostgreSQL)或SET autocommit = 0;(MySQL),避免每行都提交一次 - Navicat 的
Options > Batch Size默认是 1000,对宽表(>50 列)建议降到 100;对窄表( - 别用 Navicat 直连云数据库(如阿里云 RDS、AWS RDS),中间有代理层,容易触发连接复位;改用跳板机或本地部署的数据库代理(如
pgbouncer)中转
异构迁移最耗神的从来不是按钮点几下,而是每个字段类型、每条约束、每次连接背后的隐式假设。Navicat 不会告诉你它悄悄改了什么,只能靠日志里那一行行 [DDL] 和 [Data] 自己盯。










