快捷搜索:

PHP将数据从Oracle向Mysql数据迁移实例

为什么要迁移?

首先从运营资源斟酌,用Mysql可以节约不少的用度。另一方面,Mysql的稳定性及功能赓续地前进与增强,基础上可以满意客户的需求,如支持多 节点支配,数据分区等。还有便是Mysql应用方便,比Oracle简单易用。故客户就要求将已有的Oracle数据表与内容迁移到Mysql来。

为什么要自己写脚本?

迁移的表与数据都蛮多的,有几百张表。是以手工完成不太方便。也考试测验了一些免费的迁移对象,如:MySQLMigrationTool等,发明转移 的字段类型不太相符要求(可能是原本的Oracle表设计得不太好),会导致数据不太完备,感觉不是太靠得住,以是抉择自己写迁移脚本宁神一些,有不相符要求的也可急速调剂,以是就开始吧。

所用到的技巧支持

1.php5

2.php oci8

3.mysql 5.1

迁移表布局

获取schema所有表

用以下语句可以从Oracle中得到schema中所有的表名

SELECT table_name FROM user_tables

然后可以遍历所有表向mysql进行表布局的创建与数据的迁移事情。

获取单个表的所有字段与类型

用以下语句可以从oracle中得到单个表的所有字段与类型

SELECT COLUMN_NAME, DATA_TYPE, DATA_LENGTH, NULLABLE, DATA_DEFAULT

FROM USER_TAB_COLUMNSWHERE TABLE_NAME = UPPER('{$table_name}') ORDER BY column_id ASC

这样可以得知表字段的名称,类型,长度,是否容许为空,默认值。由于oracle与mysql的字段类型并不完全兼容,故必要建立字段类型的对应关系表。

Oracle

Mysql

number(

int

number(>11)

bigint

varchar

varchar

varchar2(

varchar

varchar2(>255)

text

clob

text

date

date

获取单个表的Primary Foreign Unique Key用以下语句可以从oracle中得到单个表的Primary Foreign Unique Key

SELECT C.CONSTRAINT_NAME, C.CONSTRAINT_TYPE, C.R_CONSTRAINT_NAME, C.DELETE_RULE,

CC.COLUMN_NAMEFROM USER_CONSTRAINTS C, USER_CONS_COLUMNS CC

WHERE C.TABLE_NAME=upper('{$table_name}') 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

获取单个表的索引

用以下语句可以从oracle中得到单个表的索引

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('{$table_name}')

这样可以获知表的索引名称,被索引的字段。

将所有的表信息组装成mysql的表布局 有了表名,字段信息,主键,Foreign, Unique.索引等信息,就可以将表布局建立起来。因为oracle没有自增字段,一个变通的措施是用primary key做为mysql中的自增字段,由于在oracle中没法子准确地知道哪个字段用到了seq来做自增,用这种措施也不是很准确。

迁移视图

获取schema所有views。用以下语句可以从oracle中获取schema所有views

SELECT VIEW_NAME,TEXTFROM USER_VIEWS

这样可以得到view的名称及建立view的组针言句。

Oracle与Mysql不兼容的view处置惩罚

Oracle的对view的构建语句对照宽松一些,mysql中对view的构建语句要严格些,from不能从子查询中构建,也便是人样的让语句是不被容许的。

CREATE VIEW `view_name` AS SELECT * FROM (SELECT * FROM table_name) ...

那么处置惩罚这样的view,有一个法子是将子查询再建立成一个view,将子查询调换成新建立的view名即可。

迁移数据

数据的迁移,从Oracle数据库中select出数据,拼装成Mysql的insert语句就可以了。必要留意的两点:一是oracle的日期类 型的数据款式与mysql的日期类型款式不太同等,以是要用TO_CHAR(field_name, 'YYYY-MM-DD')将其转换成mysql的响应的数据款式;二是oracle中的clob字段的内容要用 oci_fetch_array($stid, OCI_ASSOC|OCI_RETURN_NULLS|OCI_RETURN_LOBS)将其掏出,插入到mysql的text字段。 在mysql插入大年夜量数据时,还要留意,在window的my.ini或my.cnf默认max_allowed_packet是1M要将其改为

[mysqld]...max_allowed_packet = 16M...

要不会呈现mysql goes away的差错,linux版本没有这个问题,由于其默认值便是16M。

不能迁移的内容

Oracle中的触发器、存储历程与Mysql中是不一样的,以是不能经由过程脚本法度榜样自动迁移以前。要手工进行重写。

总结

从Oracle向Mysql数据迁移,table布局与数据是基础上可以平移以前的,view有些还不是完全兼容oracle的语句,以是要对其作 出一些中心表。触发器与存储历程是不能平移的,这两部份必要重写。表布局平移以前后,看是否都对拍照宜,假如感觉不太好还可以经由过程alter等语句对其进 行响应的调剂。在导入大年夜量数据时还要留意一下mysql的设置设置设备摆设摆设文件(my.ini或my.cnf)里的max_allowed_packet值,这应设置 得太小,以免导入数据时掉足或导不进去或乱码等不稳定身分。

您可能还会对下面的文章感兴趣: