Oracle至MySQL数据库迁移工具
最近,我重新整理了一个之前开发的小工具,用于将Oracle数据库表结构迁移至MySQL。这个小工具能够自动生成建表语句以及创建外键的SQL脚本,极大地简化了迁移过程。现在,我决定将这个工具再次优化并分享出来,一方面记录方便后续自己使用,另一方面希望可以帮助那些可能遇到相似数据库迁移挑战的朋友们,避免重复劳动,提高工作效率。
初衷
很早之前接手了一个需求,需要把Oracle数据库迁移到MySQL上。一开始,我想着找个现成的工具来帮忙,毕竟这样能省不少事儿。于是,我上网搜了搜,发现Navicat和DataWorks都挺受欢迎的,说是能一键迁移数据库结构和数据。
遇到的麻烦
但是,当我试着用这些工具迁移我们的数据库时,问题就来了。我发现,这些工具在转换字段类型的时候,经常出错。比如,Oracle里的VARCHAR2字段,有时候会被转成MySQL的TEXT,有时候又变成了LONGTEXT,看着真是让人头疼。还有INTEGER类型,也被莫名其妙地转成了DECIMAL。更别提那些应该变成LONGTEXT的字段,结果却变成了TEXT。这些问题让我意识到,如果直接用这些工具迁移,我们的数据可能会出问题,甚至可能影响业务运行。
我的解决办法
于是,我决定自己动手,写一个专门用来转换Oracle到MySQL语法的小工具。这个工具会按照我设定的规则,精确地转换字段类型,避免那些类型转换的混乱,同时考虑了联合外键、联合索引等特殊情况。转化结构完毕后,使用DataX这个开源的数据传输工具来帮忙迁移数据,支持多种数据源,传输速度也快,关键是配置起来也不难,不过需要特别注意一点,对应个别字段在Oracle中是非内部字段,但在MySQL中是内部字段,DataX转化的SQL执行时会报错,比如:sql字段,需要单独处理同步字段为`sql`,方可同步。
使用指南
-
配置自定义数据库地址或生成的SQL脚本路径
# 数据库配置,自行修改 spring: datasource: driver-class-name: oracle.jdbc.OracleDriver url: jdbc:oracle:thin:@localhost:1521:orcl username: test password: 123456 # 自定义配置 generate: # 指定字符集,默认:utf8mb4 table_charset: utf8mb4 # 指定排序规则,默认:utf8mb4_general_ci table_collation: utf8mb4_bin # 指定生成的表结构SQL脚本路径 table_structure_script_path: D:/oracle2mysql/oracle2MysqlCreateTableStructureSql.sql # 指定生成的外键SQL脚本路径 table_foreign_key_script_path: D:/oracle2mysql/oracle2MysqlTableForeignKeySql.sql
-
转化接口,可以使用浏览器或postman直接调用
/* 调用转化表结构接口 */ /api/oracle2mysql/generateTableStructure /* 调用转化生成外键接口 */ /api/oracle2mysql/generateTableForeignKey
注意事项
- 两边语法差异对照,参考博客:https://www.cnblogs.com/yeyuzhuanjia/p/17431979.html
- 当前转化规则,可根据实际情况调整(文件位置:mappers/TableFieldsAndTypesMapper.xml)
Oracle 字段类型 | 条件 | MySQL 字段类型 |
---|---|---|
VARCHAR2 | N < 255 | VARCHAR(N) |
VARCHAR2 | N = 255 或 N = 256 | VARCHAR(254) (特殊处理,长度存不满,没必要转化为TEXT) |
VARCHAR2 | N > 255 | TEXT |
NVARCHAR2 | N < 255 | VARCHAR(N) |
NVARCHAR2 | N = 255 或 N = 256 | VARCHAR(254) |
NVARCHAR2 | N > 255 | TEXT |
NUMBER | DATA_PRECISION 不为空, DATA_SCALE 不为空 | DECIMAL(DATA_PRECISION, DATA_SCALE) |
NUMBER | DATA_PRECISION 不为空, DATA_SCALE 为空, DATA_PRECISION < 3 | TINYINT(DATA_PRECISION) |
NUMBER | DATA_PRECISION 不为空, DATA_SCALE 为空, DATA_PRECISION >= 3 且 < 5 | SMALLINT(DATA_PRECISION) |
NUMBER | DATA_PRECISION 不为空, DATA_SCALE 为空, DATA_PRECISION >= 5 且 < 8 | MEDIUMINT(DATA_PRECISION) |
NUMBER | DATA_PRECISION 不为空, DATA_SCALE 为空, DATA_PRECISION >= 8 且 < 10 | INT(DATA_PRECISION) |
NUMBER | DATA_PRECISION 不为空, DATA_SCALE 为空, DATA_PRECISION > 10 | BIGINT(DATA_PRECISION) |
NUMBER | DATA_PRECISION 不为空, DATA_SCALE 为空, 其他情况 | INT |
NUMBER | DATA_PRECISION 为空, DATA_SCALE 不为空 | INT |
CHAR | CHAR_LENGTH | CHAR(CHAR_LENGTH) |
DATE | CHAR_LENGTH (忽略) | DATETIME |
FLOAT | CHAR_LENGTH (忽略) | DOUBLE |
RAW | CHAR_LENGTH = 0, DATA_LENGTH > 0 | VARCHAR(DATA_LENGTH) |
LONG 或 CLOB | CHAR_LENGTH (忽略) | LONGTEXT |
UROWID | 无对应类型 | TEXT |
其他类型 | 不在上述特殊内容中的类型可以匹配 | 按照Oracle字段转化 |
代码地址:Oracle迁移MySQL工具地址
以上就是我对Oracle迁移MySQL
的一些思考和总结,希望能对您有所帮助。由于时间和水平有限,文章中难免存在疏漏和不足之处,恳请各位朋友不吝赐教,您的每一条建议和指正都是对我最大的支持和鼓励。期待在未来的日子里,我们能一起探讨更多有趣的技术话题,共同成长。