PostgreSQL备份文件无法直接导入MySQL,因语法、数据类型、约束等存在根本差异,需借助工具转换或手动适配,并处理存储过程等无法自动迁移的对象。
PostgreSQL备份文件不能直接导入MySQL
postgresql的pg_dump输出是postgresql专有语法(比如create table ... with (fillfactor=...) 、alter table ... owner to、序列定义用owned by),mysql完全不识别。试图用mysql -u root 只会报一堆<code>syntax error或unknown database——这不是编码或权限问题,是语法层根本不兼容。
先用pg_dump生成可迁移的SQL格式
别用默认的自定义格式(-F c)或纯二进制,也别依赖--inserts就万事大吉。关键在剥离PG特有结构:
-
pg_dump --no-owner --no-privileges --column-inserts --skip-escape-string-literals -d mydb > pg_clean.sql:去掉OWNER、GRANT、转义反斜杠等MySQL讨厌的内容 - 手动删掉所有
SET default_tablespace = ...、CREATE SEQUENCE、ALTER SEQUENCE行——MySQL 8.0+虽支持序列,但语法和行为完全不同 - 把
boolean字段值true/false全替换成1/0,MySQL不认布尔字面量 -
timestamp with time zone列要降级为datetime或timestamp,并确认时区逻辑是否需在应用层补偿
用pg2mysql或sqltranslate做语法桥接
纯手工改几百张表的DDL太容易漏。轻量工具比写脚本更稳:
-
pg2mysql(Python工具)能自动转换基础DDL和INSERT,但对jsonb→json、array→text这类类型映射需人工核对 -
sqltranslate(Node.js)支持插件式规则,适合批量处理:它能把ILIKE转成LIKE+LOWER(),把||字符串拼接转成CONCAT() - 注意:所有工具都**不会**处理存储过程、触发器、函数——这些得重写,别指望自动翻译
导入前必须清理MySQL目标库的约束与引擎
MySQL对约束严格得多,尤其外键和唯一索引。直接导入常卡在ERROR 1005 (HY000): Can't create table:
- 导入前执行
SET FOREIGN_KEY_CHECKS = 0;,导入完成再设回1 - 把
ENGINE=InnoDB DEFAULT CHARSET=utf8加到每张CREATE TABLE末尾——PG导出里没这行,MySQL 5.7+默认用utf8mb4,但旧数据可能含utf8字符集声明,冲突会静默失败 - 如果原PG用了
citext扩展,MySQL没有等价物,得用COLLATE utf8mb4_0900_as_cs模拟,或在应用层统一LOWER()
真正麻烦的从来不是语法替换,而是隐式类型转换和NULL处理差异——比如PG的''::text空字符串在MySQL里可能变成NULL,取决于STRICT_TRANS_TABLES模式是否开启。











