赞
踩
将MySQL数据库的几百张表(表结构+索引)转换到Oracle数据库。
1、使用Navicat工具的数据传输(放弃)
2、使用PowerDesigner工具的反向工程 (选择此方法)
3、使用Clougence cloudcanal工具的数据同步(没有试过该方法)
1、Navicat工具的数据传输
有一些无法跳过的问题,比如MySQL中的decimal(12,2) 字段类型转换到Oracle数据库的时候变成了number类型,精度丢失。直接放弃此法。
2、PowerDesigner(v16.6)工具的反向工程
测试发现如下一些问题:
(1)反向工程连接MySQL数据库时,生成的表索引,普通的组合索引丢失,只能生成主键、唯一索引、普通单列索引。
(2)change database为Oracle后,生成的Oracle建表语句中,默认值如果是非数字的字符,引号丢失,建表报错。并且发现组合约束(多列的主键和唯一索引)字段顺序有可能发生改变,比如原来的主键是(A,B),转换后变成了(B,A)。
(3)change database时Oracle版本最高只能选到12c,对象名最长为30个字节,超过30个字节的表名会自动截去。
决定选择此方法,PowerDesigner工具只转化表结构,不转约束和索引,主键、唯一索引、普通索引通过MySQL系统表找出来,一把创建到Oracle库。默认值问题在建表脚本中手工修复。超出30个字节的对象名,在MySQL系统表中找出来,根据Oracle版本和实际使用情况处理。
3、Clougence cloudcanal工具(没有试过该方法)
朋友公司使用此工具同步不同数据库之间的数据,据说有个在线版,不过我的数据库都在本机或公司内网,所以没有试过。
单机版安装详情:https://doc-cloudcanal.clougence.com/operation/install_windows
1、安装配置MySQL的ODBC,Oracle的ODBC我没有配置,我是直接拿建表语句去Oracle库执行,而不是直接用此工具将表生成到Oracle库。(没有研究此工具,用了最简单的功能)
2、用PowerDesigner工具,反向工程连接到MySQL的ODBC,再改变数据库为Oracle,取转换后的Oracle建表语句。
step1:
step2:
step3:选择配置好的MySQL的ODBC
step4:选择需要转换的库和表,不需要转化keys和indexs,就都可以去掉勾选。
step5:改变当前数据库
step6:选择Oracle版本(v16.6版本Oracle最高可以只能选到12c)
step7:preview中查看整库的建表语句
3、建表语句手工处理后,执行到Oracle库。
去掉最前面的drop语句,去掉双引号,去掉库名,default值检查处理等。一些问题要碰到了才会发现,如字段属性长度超出等,都需要手工处理。
4、主键、唯一索引、普通索引通过MySQL系统表找出来,语句生成好,一把执行到Oracle库。
-- 五、初始化索引 -- 5.1 创建主键(主键名我以PK_表名来命名,建主键的写法可自行修改) SELECT CONCAT('ALTER TABLE ',TABLE_NAME,' ADD CONSTRAINT ',INDEX_NAME,' PRIMARY KEY (',index_details,') ;') FROM ( SELECT 'PRIMARY' AS INDEX_TYPE,TABLE_NAME,CONCAT('PK_',TABLE_NAME) AS INDEX_NAME,GROUP_CONCAT(column_name ORDER BY seq_in_index) AS index_details FROM INFORMATION_SCHEMA.STATISTICS WHERE TABLE_SCHEMA = 'test' AND INDEX_NAME='PRIMARY' GROUP BY TABLE_NAME,INDEX_NAME ) T ; -- 5.2 创建唯一索引 SELECT CONCAT('ALTER TABLE ',TABLE_NAME,' ADD CONSTRAINT ',INDEX_NAME,' UNIQUE (',index_details,') ;') FROM ( SELECT TABLE_NAME,INDEX_NAME,GROUP_CONCAT(column_name ORDER BY seq_in_index) AS index_details FROM INFORMATION_SCHEMA.STATISTICS WHERE TABLE_SCHEMA = 'test' AND INDEX_NAME<>'PRIMARY' AND INDEX_NAME IN (SELECT constraint_name FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS t WHERE t.TABLE_SCHEMA = 'test' AND CONSTRAINT_TYPE = 'UNIQUE') GROUP BY TABLE_NAME,INDEX_NAME ) T ; -- 5.3 创建普通索引 SELECT CONCAT('CREATE INDEX ',INDEX_NAME,' ON ',TABLE_NAME,'(',index_details,') ;') FROM ( SELECT TABLE_NAME,INDEX_NAME,GROUP_CONCAT(column_name ORDER BY seq_in_index) AS index_details FROM INFORMATION_SCHEMA.STATISTICS WHERE TABLE_SCHEMA = 'test' AND INDEX_NAME<>'PRIMARY' AND INDEX_NAME NOT IN (SELECT constraint_name FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS t WHERE t.TABLE_SCHEMA = 'test' AND CONSTRAINT_TYPE = 'UNIQUE') GROUP BY TABLE_NAME,INDEX_NAME ) T;
我主要检查MySQL和Oracle库的这几方面:
1、 表数量是否一致,表名是否一致(导出对比);
2、 字段数量是否一致,按字段类型分组,各组的字段数量对比;
3、 主键、唯一索引、普通索引的个数,以及对应的索引列是否一致(导出对比)。
主要检查语句:
-- 七、检查 -- 7.1 mysql -- 7.1.1 字段属性分类检查 SELECT DATA_TYPE,COUNT(1) FROM information_schema.columns WHERE TABLE_SCHEMA = 'test' GROUP BY DATA_TYPE; -- 7.1.2 表数量 SELECT * FROM information_schema.tables WHERE table_schema='test' AND TABLE_TYPE='BASE TABLE'; -- 7.1.3 索引 -- 主键 SELECT * FROM INFORMATION_SCHEMA.STATISTICS WHERE TABLE_SCHEMA = 'test' AND SEQ_IN_INDEX=1 AND INDEX_NAME='PRIMARY'; -- 非主键 SELECT * FROM INFORMATION_SCHEMA.STATISTICS WHERE TABLE_SCHEMA = 'test' AND SEQ_IN_INDEX=1 AND INDEX_NAME<>'PRIMARY'; -- 主键数量: SELECT * FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS t WHERE t.TABLE_SCHEMA = 'test' AND CONSTRAINT_TYPE = 'PRIMARY KEY'; -- 唯一索引数量: SELECT table_name,constraint_name,CONSTRAINT_TYPE FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS t WHERE t.TABLE_SCHEMA = 'test' AND CONSTRAINT_TYPE = 'UNIQUE'; -- 7.2 oracle(用户名也建成了test) -- 7.2.1 字段属性分类检查 SELECT DATA_TYPE,COUNT(1) FROM ALL_TAB_COLUMNS WHERE OWNER='test' GROUP BY DATA_TYPE ; -- 7.2.2 表数量 SELECT * FROM ALL_TABLES WHERE OWNER='test' ; -- 7.2.3 索引 -- 主键 SELECT * FROM user_constraints WHERE OWNER='test' AND constraint_type ='P'; -- 唯一索引 SELECT * FROM user_constraints WHERE OWNER='test' AND constraint_type ='U'; -- 普通索引(可能含主键和唯一索引) SELECT * FROM user_indexes WHERE TABLE_OWNER='test' AND index_type='NORMAL' AND uniqueness='NONUNIQUE';
1、Oracle索引名同一个用户下的所有表不可重复。
2、MySQL中varchar(N),Oracle中varchar2(N),两个N含义不同,一个表字符,一个表字节。
3、Oracle中字段没有自增属性,需要建序列。
等等,具体问题具体解决。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。