oracle-mysql数据迁移之主要工作内容
2015-07-22 17:51
369 查看
最近在做oracle向mysql数据迁移顺便总结一下:
感谢大神的帮忙:http://blog.csdn.net/tswisdom/article/details/8438004 ,非常的详细
我按照自己的理解总结了一下并对于迁移中的细节处理的心得也总结一下:
基本步骤:
--1 迁移表
-- 1.1 获取schema所有表
select t.table_name from user_tables t
-- 1.2 获取单个表的所有字段与类型
-- 1.3 获取单个表的Primary Foreign Unique Key用以下语句可以从oracle中获得单个表的Primary Foreign Unique Key
-- 1.4 获取单个表的索引
-- 2 迁移视图
-- 2.1 获取schema所有views
-- Oracle与Mysql不兼容的view处理
--Oracle的对view的构建语句比较宽松一些,mysql中对view的构建语句要严格些,from不能从子查询中构建,也就是人样的让语句是不被允许的。
--如:CREATE VIEW `view_name` AS SELECT * FROM (SELECT * FROM table_name)
--解决方法:那么处理这样的view,有一个办法是将子查询再建立成一个view,将子查询替换成新建立的view名即可
--3 迁移数据
通过程序利用1.2和1.3 拼凑成query语句先从oracle里取出数据,然后还是利用1.2和1.3 拼凑成add语句插入mysql,2种库的类型不一致问题,通过程序转换如下:
这图也是那位大神的,呵呵 copy一下而已,至于其他类型 ,我没涉及,大家可以自己查查
--4 不能迁移的内容
--Oracle中的触发器、存储过程与Mysql中是不一样的,所以不能通过脚本程序自动迁移过去。
以上内容基本和地址上的内容相同,主要是为了备份下。
下面我说说到迁移中遇到的细节:
细节一 :在1.1中涉及要通过那个sql查询出所有表,不幸的是:我遇到很多莫名其妙的表,表名是很多胡乱的字符拼起来的,还挺长,由于没有规则,我无法使用where语句
进行过滤。
解决方法一:用exp导出oracle的库,加上statistics=none 后 ,然后删了用户,再用这个重新导入一次,就没有了。
解决方法二:之所以我会发现方法二,是因为我的导出工作和其他人开发工作是并行的,同时时间问题无法验证方法一是一定可行的。方法二是:我还是利用1.1取出所有的表,然后遍历每一个表名,进入1.2的sql语句来查询对应表下的字段信息,我发现所有莫名的表都是空字段的,于是我通过list !=null&&;list.size()>0就过滤掉他们了
细节二:1.3中是关于表中主键和外键的信息,配置1.2可以生成每个表在mysql的创建sql。
细节三:关于视图的迁移,当初我在oracle中就很少用视图,大部分都是复杂的查询语句(因为oracle的强大,懒得用视图,直接用select嵌套),当初需求也要求支持多数据库,我知道mysql的视图不支持子查询,很麻烦,在oracle开发中我就尽量少用视图,(估计性能....),我既然用了大量的select嵌套,在oracle中没问题,迁移到mysql大家一定要注意:select * from (子查询) 或是 select name ,id from (子查询) oracle中没问题,mysql 这种写法是不行的,在mysql中必须为子查询加上别名(尽管没啥用):
我这里涉及到 “合并列” 、“行变列”、“列边行”,我打算单独拿出总结下,就不在这里写了
细节五:建议大家在写关联查询sql时,尽量使用通用的sql,如:
select a.id ,b.name from a join b on b.id=a.id 或者 select a.id ,b.name from a left join b on b.id=a.id
如果你早知道项目必须支持多数据库时,就不要使用oracle特有的语法,如:
select a.id ,b.name from a ,b where b.id=a.id(+) 或者 select a.id ,b.name from a ,b on b.id(+)=a.id以上仅代表个人意见,说的不对便是我学习不足吧,希望大家多指点
感谢大神的帮忙:http://blog.csdn.net/tswisdom/article/details/8438004 ,非常的详细
我按照自己的理解总结了一下并对于迁移中的细节处理的心得也总结一下:
基本步骤:
--1 迁移表
-- 1.1 获取schema所有表
select t.table_name from user_tables t
-- 1.2 获取单个表的所有字段与类型
SELECT COLUMN_NAME, DATA_TYPE, DATA_LENGTH, NULLABLE, DATA_DEFAULT FROM USER_TAB_COLUMNS WHERE TABLE_NAME = UPPER('xxxTableName') ORDER BY column_id ASC
-- 1.3 获取单个表的Primary Foreign Unique Key用以下语句可以从oracle中获得单个表的Primary Foreign Unique Key
SELECT c.table_name,C.CONSTRAINT_NAME, C.CONSTRAINT_TYPE, C.R_CONSTRAINT_NAME, C.DELETE_RULE, CC.COLUMN_NAME FROM USER_CONSTRAINTS C, USER_CONS_COLUMNS CC WHERE C.TABLE_NAME=upper('xxxTableName') AND C.CONSTRAINT_TYPE!='C' AND C.CONSTRAINT_NAME=CC.CONSTRAINT_NAME AND C.OWNER=CC.OWNER AND C.TABLE_NAME=CC.TABLE_NAME ORDER BY C.CONSTRAINT_TYPE, C.CONSTRAINT_NAME, CC.POSITION
-- 1.4 获取单个表的索引
SELECT T.INDEX_NAME,T.COLUMN_NAME,I.INDEX_TYPE FROM USER_IND_COLUMNS T,USER_INDEXES I WHERE T.INDEX_NAME = I.INDEX_NAME AND T.TABLE_NAME = I.TABLE_NAME AND T.TABLE_NAME = UPPER('xxxTableName')
-- 2 迁移视图
-- 2.1 获取schema所有views
SELECT VIEW_NAME,TEXT FROM USER_VIEWS
-- Oracle与Mysql不兼容的view处理
--Oracle的对view的构建语句比较宽松一些,mysql中对view的构建语句要严格些,from不能从子查询中构建,也就是人样的让语句是不被允许的。
--如:CREATE VIEW `view_name` AS SELECT * FROM (SELECT * FROM table_name)
--解决方法:那么处理这样的view,有一个办法是将子查询再建立成一个view,将子查询替换成新建立的view名即可
--3 迁移数据
通过程序利用1.2和1.3 拼凑成query语句先从oracle里取出数据,然后还是利用1.2和1.3 拼凑成add语句插入mysql,2种库的类型不一致问题,通过程序转换如下:
这图也是那位大神的,呵呵 copy一下而已,至于其他类型 ,我没涉及,大家可以自己查查
--4 不能迁移的内容
--Oracle中的触发器、存储过程与Mysql中是不一样的,所以不能通过脚本程序自动迁移过去。
以上内容基本和地址上的内容相同,主要是为了备份下。
下面我说说到迁移中遇到的细节:
细节一 :在1.1中涉及要通过那个sql查询出所有表,不幸的是:我遇到很多莫名其妙的表,表名是很多胡乱的字符拼起来的,还挺长,由于没有规则,我无法使用where语句
进行过滤。
解决方法一:用exp导出oracle的库,加上statistics=none 后 ,然后删了用户,再用这个重新导入一次,就没有了。
解决方法二:之所以我会发现方法二,是因为我的导出工作和其他人开发工作是并行的,同时时间问题无法验证方法一是一定可行的。方法二是:我还是利用1.1取出所有的表,然后遍历每一个表名,进入1.2的sql语句来查询对应表下的字段信息,我发现所有莫名的表都是空字段的,于是我通过list !=null&&;list.size()>0就过滤掉他们了
细节二:1.3中是关于表中主键和外键的信息,配置1.2可以生成每个表在mysql的创建sql。
细节三:关于视图的迁移,当初我在oracle中就很少用视图,大部分都是复杂的查询语句(因为oracle的强大,懒得用视图,直接用select嵌套),当初需求也要求支持多数据库,我知道mysql的视图不支持子查询,很麻烦,在oracle开发中我就尽量少用视图,(估计性能....),我既然用了大量的select嵌套,在oracle中没问题,迁移到mysql大家一定要注意:select * from (子查询) 或是 select name ,id from (子查询) oracle中没问题,mysql 这种写法是不行的,在mysql中必须为子查询加上别名(尽管没啥用):
select * from (子查询) v 或是 select name ,id from (子查询) t细节四:触发器没用到,存储过程的转换
我这里涉及到 “合并列” 、“行变列”、“列边行”,我打算单独拿出总结下,就不在这里写了
细节五:建议大家在写关联查询sql时,尽量使用通用的sql,如:
select a.id ,b.name from a join b on b.id=a.id 或者 select a.id ,b.name from a left join b on b.id=a.id
如果你早知道项目必须支持多数据库时,就不要使用oracle特有的语法,如:
select a.id ,b.name from a ,b where b.id=a.id(+) 或者 select a.id ,b.name from a ,b on b.id(+)=a.id以上仅代表个人意见,说的不对便是我学习不足吧,希望大家多指点
相关文章推荐
- oracle创建用户
- dmp文件导入导出oracle数据库命令
- oracle启动快捷键设置
- Oracle锁定和解锁用户的命令
- oracle 10g RAC重启步骤
- 如何使用log miner分析oracle日志
- OracleHelper类
- C#.NET万能数据库访问封装类(ACCESS、SQLServer、Oracle)
- oracle印象之基础
- oracle恢复删除的数据
- java中的反射 1—— 简介@译自Oracle官方文档
- java中的反射 2.0—— 类@译自Oracle官方文档
- Oracle连接数据库封装类
- java中的反射 2.1——类:获取类对象@译自Oracle官方文档
- java中的反射 2.2——类:检查一个类的声明信息@译自Oracle官方文档
- java中的反射 2.3——类:发现类成员@译自Oracle官方文档
- java中的反射 2.4——类:常见问题@译自Oracle官方文档
- oracle中一些命令
- ORACLE 12C新特性——CDB与PDB
- oracle官方中文博客地址