Navicat不支持PostgreSQL到MariaDB一键迁移,因SQL方言差异大、DDL转换能力弱,需分三步:手动改写pg_dump导出的DDL适配MariaDB语法,建好表结构后再用Navicat仅传输数据,并严格配置字符集utf8mb4及禁用自动建表/索引/外键。
navicat premium 支持跨类型数据库迁移,但 postgresql 到 mariadb 不是“一键平移”,必须手动处理类型兼容性、语法差异和约束转换。直接使用「数据传输」功能容易失败或丢数据,尤其在遇到 array、jsonb、enum、序列(serial)、默认值表达式(如 now())时。
为什么不能直接用“数据传输”全选导出导入
PostgreSQL 和 MariaDB 的 SQL 方言差异大,Navicat 的跨库传输模块对 DDL 转换能力有限:
- TEXT 在 PostgreSQL 中可带长度限制,在 MariaDB 中不生效
- BOOLEAN 类型在 MariaDB 里实际存为 TINYINT(1),但 Navicat 不自动映射
- UUID 类型在 MariaDB 需用 CHAR(36) 或 BINARY(16) 替代,Navicat 默认不处理
- GENERATED ALWAYS AS(计算列)在 MariaDB 8.0+ 才支持,且语法不同
- 外键引用的表名/列名若含大小写或双引号(PostgreSQL 默认小写但保留引号),MariaDB 会报错 ERROR 1005 (HY000): Can't create table
推荐流程:分三步走,DDL + 数据分离
绕过 Navicat 的“自动建表”逻辑,自己控制结构和数据迁移节奏:
- 先用
pg_dump --schema-only导出 PostgreSQL 的建表语句,手动改写成 MariaDB 兼容版本(比如把CREATE TABLE "user"改成CREATE TABLE `user`,把jsonb换成JSON,把serial换成INT AUTO_INCREMENT PRIMARY KEY) - 在 MariaDB 中执行改写后的 DDL,确认表创建成功且引擎为
InnoDB(避免 MyISAM 不支持外键) - 再用
Navicat的「数据传输」功能,仅勾选「插入记录」,取消勾选「创建表」「包含索引」「包含外键限制」——让 Navicat 只负责搬运数据,不碰结构
数据传输时关键设置项
进入「数据传输」向导后,左侧选 PostgreSQL 源,右侧选 MariaDB 目标库(需已存在且表结构就绪),点击「高级」按钮调整:
- 务必取消勾选
创建表—— 否则 Navicat 会尝试生成 PostgreSQL 风格 DDL,大概率失败 - 取消勾选
包含索引和包含外键限制—— 索引和外键应在 DDL 阶段手动加,否则可能因字段顺序/类型不匹配报错 - 勾选
运行多重插入语句和使用扩展插入语句—— 加快大批量导入速度(如单条INSERT INTO t VALUES (1,'a'),(2,'b')比多条INSERT快 3–5 倍) - 根据数据量决定是否勾选
遇到错误继续:如果表中有少量脏数据(如空字符串插入NOT NULL字段),勾选它可跳过单行错误;但要配合日志检查,别让它默默吞掉关键报错
容易被忽略的字符集与排序规则问题
MariaDB 默认字符集是 latin1,而 PostgreSQL 通常用 UTF8。如果 Navicat 连接 MariaDB 时没显式指定 charset=utf8mb4,中文或 emoji 会变成问号或乱码:
- 在 MariaDB 连接配置里,「高级」选项卡中手动填入
charset=utf8mb4(不是utf8,后者不支持 4 字节 Unicode) - 建表时显式声明:例如
CREATE TABLE `user` (...) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci - Navicat 导入过程中若提示
Incorrect string value,基本就是这个原因,回退检查连接参数和建表语句
真正卡住人的不是操作步骤,而是 PostgreSQL 和 MariaDB 对“相同概念”的实现差异——比如 NULL 处理、默认值求值时机、时间类型精度截断。建议先拿一张小表试跑,比对源库和目标库的 COUNT(*)、MD5(GROUP_CONCAT(...)),确认数据一致后再批量迁移。


















