异构数据库迁移的类型映射是怎么实现的?——以 MySQL → PostgreSQL 为例
一、为什么类型映射是异构迁移最难的部分
数据库迁移工具看起来简单——读数据、写数据。但真正做过异构迁移的人都知道,最复杂的不是数据传输本身,而是 SQL 方言转换和数据类型映射。
Oracle 的 NUMBER 精度与 MySQL 的 DECIMAL 存在微小差异,在金融计算场景中可能导致舍入误差;SQL Server 的 DATETIME 与 PostgreSQL 的 TIMESTAMP 在时区处理逻辑上不一致,跨时区应用需要逐条检查时间相关 SQL-1。这些差异在应用层可能不会被立即发现,但会在特定业务场景下产生静默错误。
DBBridge 解决这个问题的核心思路是:两层映射 + 约束校验。
二、两层映射架构
DBBridge 的类型映射引擎采用“中间类型”模型:源库类型先映射到抽象的中间类型,再由中间类型映射到目标库的具体类型。
这样做的好处是:新增一种数据库时,只需要定义“中间类型 → 目标类型”的映射规则,而不需要为每种源库单独配置。在 10 种数据库的 N×N 迁移矩阵中,这意味着维护成本从 N² 降到 2N。
中间类型的分类体系:
| 中间类型 | 说明 | 典型源类型举例 |
|---|---|---|
| TYPE_INT | 整数类型 | MySQL INT、PG INTEGER、达梦 INT |
| TYPE_DECIMAL | 精确小数 | MySQL DECIMAL、Oracle NUMBER(p,s) |
| TYPE_VARCHAR | 变长字符串 | MySQL VARCHAR、PG VARCHAR |
| TYPE_TEXT | 大文本 | MySQL TEXT/LONGTEXT、PG TEXT |
| TYPE_TIMESTAMP | 时间戳 | MySQL DATETIME、PG TIMESTAMP |
| TYPE_BOOLEAN | 布尔值 | MySQL TINYINT(1)、PG BOOLEAN |
| TYPE_JSON | JSON 数据 | MySQL JSON、PG JSONB |
| TYPE_BINARY | 二进制 | MySQL BLOB、PG BYTEA |
三、约束校验:不只是类型名匹配
仅仅做类型名的映射是不够的。同一个中间类型 TYPE_VARCHAR,MySQL 的 VARCHAR(255) 和 PostgreSQL 的 VARCHAR(255) 在行为上可能存在差异——字符集、排序规则、长度语义(字节 vs 字符)都可能不同。
DBBridge 在类型映射时引入了约束属性的概念:
- 长度约束:源类型的最大长度映射到目标类型时,如果目标类型不支持相同长度,自动升格
- 精度约束:
DECIMAL(p,s)的精度和小数位数需要精确映射 - 编码约束:字符集和排序规则的映射(如 MySQL 的
utf8mb4_unicode_ci到 PostgreSQL 的UTF8+LC_COLLATE) - 可空约束:
NOT NULL属性的保留 - 默认值约束:表达式类型的默认值需要转换语法
以 NUMBER(10,2) → DECIMAL(10,2) 为例,表面上是简单的类型替换,但 DBBridge 在映射时会检查:目标库的 DECIMAL 最大精度是否满足(PostgreSQL 支持最大 1000 位精度,MySQL 支持最大 65 位)、小数位数是否超出范围、以及是否需要在迁移报告中标记精度损失风险。
四、SQL 方言转换:比类型映射更复杂
类型映射解决的是“字段定义”的问题,SQL 方言转换解决的是“查询和 DDL 语句”的问题。
DDL 层面的转换包括:
- 自增字段:
AUTO_INCREMENT→SERIAL/IDENTITY/SEQUENCE - 存储引擎声明:
ENGINE=InnoDB→ 删除或替换 - 字符集声明:
CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci→ENCODING 'UTF8' - 索引类型:
USING BTREE→ 目标库对应的索引语法
DML 层面的转换包括:
- 分页查询:MySQL 的
LIMIT offset, count→ PostgreSQL 的LIMIT count OFFSET offset - 字符串拼接:SQL Server 的
+→ PostgreSQL 的|| - 空值处理:MySQL 的
IFNULL()→ PostgreSQL 的COALESCE() - 时间函数:MySQL 的
NOW()→ PostgreSQL 的CURRENT_TIMESTAMP
DBBridge 的做法不是简单的字符串替换,而是解析 SQL 语法树,识别出需要转换的节点,再根据目标数据库的语法规则重新生成 SQL。这种方式比正则替换更安全,能正确处理嵌套表达式和字符串中的特殊字符。
五、迁移报告中的类型映射透明化
类型映射有一个容易被忽视的问题:用户不知道映射结果是否正确。
DBBridge 的迁移报告会列出每张表的类型映射详情:
表 users:
id MySQL INT AUTO_INCREMENT → PG SERIAL ✓
name MySQL VARCHAR(255) → PG VARCHAR(255) ✓
balance MySQL DECIMAL(10,2) → PG DECIMAL(10,2) ✓
metadata MySQL JSON → PG JSONB ✓
created_at MySQL DATETIME → PG TIMESTAMP ⚠ 时区信息丢失
对于无法自动映射或存在精度损失风险的类型,用 ⚠ 标记,提示人工复核。这种透明化设计让用户对迁移结果有清晰的预期,而不是迁移完了才发现问题。
六、总结
类型映射是异构数据库迁移中最容易被低估的环节。DBBridge 的两层映射架构和约束校验机制,把一个看似简单的“类型名替换”问题,拆解成了可控的、可验证的工程问题。
代码开源在
GitHub:suoten/dbbridge,Gitee:suoten/dbbridge,类型映射引擎的实现位于 internal/typeconv/ 目录,感兴趣的可以阅读源码。

浙公网安备 33010602011771号