添加链接
link之家
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接

一、概述

现在有个需求,想把 mysql 数据库中的数据转移到 oracle 数据库中,网上找了好几种方法,最后决定使用 oracel sql developer 这种工具来实现。

Mysql oracle 属于两种不同的数据库,具体使用差异也有很多,不能简单使用 sql 文件进行导出导入。以下几个示例比较一下 Mysql oracle 数据库的差异

l SQL 基本语法差异

MySQL SQL 语句中,要求表名、表的别名必须区分大小写(可通过修改 mysql 配置文件 my.cnf ,增加 lower_case_table_names=1 来忽略大小写,从而与 Oracle 尽量保持一致),尤其是表的别名。建议通过组内开发规范统一起来,以消除差异性。

MySQL Insert 语句,支持 ignore 语法忽略主键冲突报错,如: insert ignore into table_name... ;支持 insert into ... on duplicate key update... 的用法,此时要求表必须有主键或唯一性约束字段。

insert 语句类似, MySQL 还支持 replace into 语句,若插入表中已存在数据时,则用新数据记录替换旧的记录。

l 建表语句差异

创建表时, MySQL 不支持 create or replace ,但可以通过 drop table if exists tbl_name 来重新创建表。

另外,在建表语句、建索引语句中, MySQL 不支持 tablespace 后缀。此时,可以将 Oracle 导出的 DDL 语句中, tablespace 部分注释掉;同时,在导入 MySQL 数据库时,先执行 set @@sql_mode='oracle' 以尽量保持与 Oracle 语法一致。具体 sql_mode ,可参考 MySQL 官方手册等文档

l 内置函数差异

具体参考 https://www.cnblogs.com/HondaHsu/p/3641190.html

l 表主键取值差异

MySQL 不支持 Sequence ,在表中可设置自增主键。如与 Oracle 兼容,可考虑统一采用 function 来封装主键取值差异。

l 存储过程差异

对于存储过程而言, Oracle PLSQL MySQL 也是有较大不同的,比如, MySQL 不支持包、不支持常量定义、不支持 dbms_output 调试……具体细节以后另外整理。

l 视图差异

MySQL 的视图 from 语句中不允许存在子查询,可以通过将子查询创建为新的视图的方式解决。 Oracle 的物化视图相关概念,在 MySQL 中也不存在。

二、环境准备

1 mysql 准备工作

mysql 创建测试数据,建立一个库,再建立一个表,随便插入两条数据

[root@DB mysqldb]# mysql -uroot -p 
Enter password: 
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 23
Server version: 5.1.73 Source distribution
Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
mysql> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |      |
| mysql              |
| test               |
+--------------------+
3rows in set (0.12 sec)
mysql> create database test1;
Query OK, 1 row affected (0.03 sec)
mysql> use test1
Database changed
mysql> create table tb1(name varchar(20),age int);
Query OK, 0 rows affected (0.06 sec)
mysql> insert into tb1 values("tom",18);
Query OK, 1 row affected (0.00 sec)
mysql> insert into tb1 values("jerry",20);
Query OK, 1 row affected (0.00 sec)
mysql> select * from tb1;
+-------+------+
| name  | age  |
+-------+------+
| tom |   18 |
| jerry |   20 |
+-------+------+
2 rows in set (0.03 sec)
mysql> exit
Bye


2 Oracle 准备工作

Mysql 中,数据库和用户之间的关系不是特别明显,只要我们链接到 Mysql 服务器,可以看到所有的数据库和表,而 Oracle 新建一个用户是没有任何资源和权限的,需要我们为其分配资源权限,也可以在这个用户下面建立表,但不能向 Oracle 那样建数据库,因为对 oracle 来说 , 一个用户就对应 Mysql 的一个数据库。所以迁移数据库 , 需要在 Oracle 中创建一个与相应 mysql 数据库同名的用户(我这里要迁移的 mysql 数据库是 test1 ,创建的 oracle 用户名是 test1 .

这种情况要注意 oracle 数据库的用户名。因为 sql developer mysql 转换到 oracle 数据库中时,会把 mysql 的数据存放到一个用户下,这个用户名一定会和 mysql 的数据库名相同。如果 oracle 中已有这个用户,则数据直接导入到该用户下;如果没有这个用户,则 sql developer 会直接创建这样的用户,并把数据导入到该用户下。需要注意的是, sql developer 默认创建的 oracle 数据库用户的默认表空间是 user ,如果不注意,很有可能会导致 user 表空间爆满!所以这种情况最好先建一个和 mysql 数据库名一样的 oracle 用户,以防止 user 表空间爆满影响数据导入。

-- 创建表空间

CREATE TABLESPACE MY_TEST DATAFILE '/opt/oracle/oradata/test/MY_TEST.dbf' SIZE 100M 
    AUTOEXTEND ON NEXT 100M MAXSIZE UNLIMITED
    EXTENT MANAGEMENT LOCAL
SEGMENT SPACE MANAGEMENT AUTO;


-- 创建用户

CREATE USER test1 IDENTIFIED BY  test1 DEFAULT TABLESPACE MY_TEST TEMPORARY TABLESPACE TEMP;
GRANT CONNECT TO test1;
GRANT RESOURCE TO test1;
GRANT DBA TO test1;
GRANT UNLIMITED TABLESPACE TO test1;


3 、所需要工具的安装配置

oracel sql developer 获取地址:

http://www.oracle.com/technetwork/developer-tools/sql-developer/downloads/index.html

mysql-connector-java-5.1.44-bin.jar 获取地址

http://download.softagency.net/mysql/Downloads/Connector-J/

MYSQL数据库迁移到ORACLE数据库_oracle sql develope

1 是集成 jdk 的安装程序,支持 windows64 位的操作系统,不用自己额外安装 jdk 环境;

2 是不包含 jdk 的安装程序,可以支持 windows64 位和 windows32 位的操作;

3 可以选择之前的几个版本。

我这里下载的是 sqldeveloper-4.1.3.20.78-x64.zip

注:

1 如果安装过程中出现一下错误,需要用 360 扫一下注册表,重新安装一些补丁包就行了:

MYSQL数据库迁移到ORACLE数据库_oracle_02

2移植过程最后可能出现下面提示:捕获期间出错,调用中的无效参数

MYSQL数据库迁移到ORACLE数据库_oracle_03

移植报告内容如下:

MYSQL数据库迁移到ORACLE数据库_oracle sql develope_04

我这里查了网上资料也没找到具体原因,只是换了一个 低版本 oracle sql developer 再次移植操作就 OK 了。所以劝大家最好不要使用最新版的 oracle sql developer 。不知道是不是涉及了兼容性的问题

4 、配置 oracle sql developer 连接 mysql

依次选择 “工具” --> “首选项”,在弹出的界面选择“数据库” --> “第三方 JDBC 驱动程序”

MYSQL数据库迁移到ORACLE数据库_oracle sql develope_05

创建 oracle 的连接

MYSQL数据库迁移到ORACLE数据库_oracle sql develope_06

创建 mysql 的连接

MYSQL数据库迁移到ORACLE数据库_mysql_07

可以看到已经连接上两个数据库了

MYSQL数据库迁移到ORACLE数据库_oracle_08

三、开始移植

1. 删除之前的移植资料库

为充分能完成移植,不知数据库之前有没有移植过,所以先把原来的移植资料库

MYSQL数据库迁移到ORACLE数据库_oracle sql develope_09

MYSQL数据库迁移到ORACLE数据库_mysql_10

2. 开始移植操作

MYSQL数据库迁移到ORACLE数据库_mysql_11


MYSQL数据库迁移到ORACLE数据库_oracle_12


MYSQL数据库迁移到ORACLE数据库_mysql_13

MYSQL数据库迁移到ORACLE数据库_oracle sql develope_14


MYSQL数据库迁移到ORACLE数据库_mysql_15

选择要转换的mysql数据库,添加到列表中:

MYSQL数据库迁移到ORACLE数据库_oracle_16

指定转换规则,可以根据自己的情况设定字段属性的转换,也可以新添加规则。不过一般选择默认的就能满足需求

MYSQL数据库迁移到ORACLE数据库_oracle sql develope_17

MYSQL数据库迁移到ORACLE数据库_mysql_18

MYSQL数据库迁移到ORACLE数据库_mysql_19

如果只导表结构不导数据,要勾选截断数据

MYSQL数据库迁移到ORACLE数据库_mysql_20

MYSQL数据库迁移到ORACLE数据库_oracle sql develope_21

MYSQL数据库迁移到ORACLE数据库_mysql_22

MYSQL数据库迁移到ORACLE数据库_mysql_23

可以看到在输出目录下面生成了几个文件,打开前两个看一下:

MYSQL数据库迁移到ORACLE数据库_oracle sql develope_24

MYSQL数据库迁移到ORACLE数据库_mysql_25

MYSQL数据库迁移到ORACLE数据库_mysql_26

四、数据验证

Oracle sql developer HSDB 可以看到在数据库中能多了一个 test1 用户,执行查询语句也能查到数据,和上面在 mysql 中查到的结果一致

MYSQL数据库迁移到ORACLE数据库_oracle_27

我尝试移植过另一个数据量比较大的库。如果是导入的 mysql 库中的数据量比较大,并不会立即就能查到数据,这是由于 oracle 有个统计分析的机制。

统计信息主要是描述数据库中表,索引的大小,规模,数据分布状况等的一类信息。例如,表的行数,块数,平均每行的大小,索引的 leaf blocks,索引字段的行数,不同值的大小等,都属于统计信息。CBO正是根据这些统计信息数据,计算出不同访问路径下,不同join 方式下,各种计划的成本,最后选择出成本最小的计划。

可以使用 oracle 自带的 dbms_stats 程序包 进行手动收集系统统计信息。 DBMS_STATS 包,主要提供了搜集( gather ),删除( delete ),导出( export ),导入( import ),修改( set )统计信息的方法 。我在这里使用的语句如下:

exec dbms_stats.delete_schema_stats('TEST1');
exec dbms_stats.gather_schema_stats(ownname =>'TEST1',degree => 4,cascade => true);