迁移目标是MySQL时,DDL自动转换实质是生成兼容MySQL语法的SQL,而非简单转译;需依赖源库反向解析能力、目标MySQL兼容模式及工具对语义差异(如IDENTITY/AUTO_INCREMENT)的处理。

直接说结论:迁移目标是MySQL时,DDL自动转换通常不是“转成MySQL”,而是“转成兼容MySQL语法的SQL”——关键在源库是否支持反向解析、目标MySQL版本是否启用兼容模式、以及工具能否处理语义级差异(比如达梦的IDENTITY vs MySQL的AUTO_INCREMENT)。
为什么不能直接用MySQL自带工具做异构DDL转换
MySQL官方没有提供从Oracle/达梦/金仓等数据库反向生成MySQL DDL的能力。mysqldump只支持MySQL自身导出,mysqlpump也不接受非MySQL源。你拿到的Oracle建表语句,MySQL根本不会认CREATE SEQUENCE或NUMBER(10,2)这种写法,更别说达梦的"USER"."USER"双引号模式或金仓的COMMENT ON COLUMN语法。
常见错误现象包括:
- 执行时报错
ERROR 1064 (42000): You have an error in your SQL syntax,往往卡在第一个非MySQL关键字上 - 字段类型映射后精度丢失,比如把Oracle的
NUMBER(15,4)硬转成DECIMAL(10,2),导致插入失败 - 注释被整个丢弃,或者
COMMENT 'xxx'被插到错误位置,引发语法错误
主流工具链中真正能跑通的转换路径
目前能落地的方案基本分两类:一类是数据库厂商提供的DTS工具(如达梦DTS、金仓KDTS),另一类是开源/自研的SQL解析器(如JSqlParser + 自定义规则)。它们的共同前提是:先将源DDL解析为AST(抽象语法树),再按MySQL语法规则重写节点。
实操建议:
安装、修复、更新或打包一个基于 Python 和 PyMySQL 实现的 Windows `mysql` 命令。适用于用户希望在 PowerShell/CMD 中输入 `mysql` 时重定向到 Python 实现、需要交互式输入 MySQL 连接信息、需要同步到当前用户本地 bin 目录,或需要将该能力封装成可公开复用的 Codex skill。
- 达梦迁移至MySQL:必须先在达梦端执行
ALTER SYSTEM SET 'compatible_mode'=4,否则DROP TABLE IF EXISTS这类MySQL风格语句无法被识别,工具预扫描会直接报错 - Oracle迁移至MySQL:优先用
DBMS_METADATA.GET_DDL导出标准DDL,再过滤掉SEGMENT CREATION、LOGGING、TABLESPACE等MySQL不支持的子句;DATE类型统一映射为DATETIME,别碰SYSDATE——得换成NOW() - 金仓迁移至MySQL:注意其
IDENTITY列在MySQL 8.0+才支持AUTO_INCREMENT,若目标MySQL是5.7,必须降级为INT NOT NULL+ 应用层维护ID
绕不开的三个语义陷阱
字符集、约束顺序、默认值表达式,这三项在自动转换中最容易被当成纯字符串替换,结果上线就翻车。
举例说明:
- 达梦的
CHARACTER SET UTF8MB4要转成MySQL的CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci,漏掉COLLATE会导致中文排序异常 - Oracle建表里
UNIQUE KEY写在PRIMARY KEY之后,MySQL虽不报错但索引顺序影响查询计划;自动工具若不重排CONSTRAINT定义顺序,可能让唯一索引失效 - MySQL 8.0.23+才支持
CURRENT_TIMESTAMP() ON UPDATE CURRENT_TIMESTAMP()带括号写法,老版本必须去掉括号,否则DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP才是合法的
真正难的从来不是把CREATE TABLE改出来,而是让生成的DDL在MySQL里建出来的表,行为和原库一致——时间函数返回值、空字符串处理、隐式类型转换、甚至GROUP BY是否严格模式,这些都得在转换规则里显式控制。没做过全量schema比对和边界值插入验证,就别信“一键迁移”。










