Oracle 迁移至Mysql

**吴海存,**10g / 11g / 12c OCM,Oracle Exadata / Golden Gate专家,曾于Amazon和Oracle公司担任全球业务资深DBA,目前供职于中国农业银行,负责数据库前沿技术研究和支持。

导读

随着MySQL 8.0的发布,MySQL的功能和性能有了较大的增强,越来越多的企业都选择了使用成本低且部署方案灵活的MySQL数据库。那么,将数据从当前数据库迁移到MySQL时,从应用层、数据库层都需要注意哪些方面?为了顺利完成复杂的迁移工作又需要考虑和解决哪些方面的问题?

本文以Oracle迁移到MySQL为例,重点阐述Oracle和MySQL数据类型差异、业务实现差异、迁移方式以及迁移过程中的一些风险点,供大家参考,文中如有疏漏之处,望在评论区指正。

在异构数据库迁移过程中,我们从如下几个方面进行思考:

1、迁移类型

Oracle迁移到MySQL主要涉及数据结构迁移、数据迁移、业务迁移这三类,我们需要考虑如下几个难点:

  • 数据类型差异导致数据结构迁移过程中需要进行改造和处理;
  • 数据迁移中 Oracle LOB字段、null值和’’值以及迁移方式为迁移难点。
  • 业务迁移中由于MySQL不支持并行、不支持物化视图,会涉及到存储过程改造,同义词改造,DBlink、sequence、分区表以及复杂sql语句的改造。

2、迁移流程

我们需要整理一个完整的迁移流程:1、确定迁移范围;2、迁移评估;3、选择迁移方式;4、迁移验证,以此来确保迁移工作的进展和顺利完成。

1)确定迁移范围

从Oracle迁移到MySQL是一项昂贵且耗时的任务,重要的是要了解要迁移的范围,不要浪费时间来迁移不再需要的对象。另外,检查是否需要迁移所有的历史数据,不要浪费时间来复制不需要的数据,例如过去维护中的备份数据和临时表。

2)迁移评估

经过初步检查后,迁移的第一步是分析应用程序和数据库对象,找出两个数据库之间不兼容的特性,并估算迁移所需的时间和成本。例如由于Oracle与MySQL之间数据结构存在差异,且MySQL不支持并行、不支持物化视图、8.0以上才支持函数索引,可能涉及到存储过程改造,同义词改造,DBlink、sequence、分区表以及复杂sql语句的改造等工作。

3)迁移方式

通过对迁移所需时间和成本选择不同的迁移方法或者工具进行迁移,可以分为实时复制(例如利用GoldenGate实时同步数据使业务影响时间最小),或者一次性加载(例如采用 Oracle将数据表导出到csv文件后,通过load或者mysqlsh工具导入到MySQL中)。

4)验证测试

测试整个应用程序和迁移的数据库非常重要,因为两个数据库中的某些功能相同,但是实现方式和机制却是不同的。我们需要做充分的验证测试:

  • 检查是否正确转换了所有对象;
  • 检查所有DML是否正常工作;
  • 在两个数据库中加载样本数据并检查结果,比如来自两个数据库的SQL结果应该相同;
  • 检查DML及查询SQL的性能,并在必要时进行SQL改造。

首先,我们先从术语、元数据、表对象、索引类型、分区等方面了解一下Oracle和MySQL的差异和区别。

一、MySQL和Oracle差异

1.1 MySQL和Oracle术语差异

1.2 MySQL和Oracle配置用户差异

1.3 MySQL和Oracle对表的限制差异

1.4 MySQL和Oracle虚拟列和计算列差异

Oracle和MySQL的虚拟列(在MySQL中也称为生成的列)基于其他列的计算结果。它们显示为常规列,但它们的值是计算所得,因此它们的值不会存储在数据库中。虚拟列可与限制条件、索引、表分区和外键一起使用,但无法通过 DML 操作操纵。

与Oracle的虚拟列相反MySQL生成的列必须指定计算列的数据类型。必须指定GENERATED ALWAYS值,如以下示例中所示:

Oracle虚拟列:

SQL> CREATE TABLE PRODUCTS (

        PRODUCT_ID     INT PRIMARY KEY,

        PRODUCT_TYPE   VARCHAR2(100) NOT NULL,

        PRODUCT_PRICE  NUMBER(6,2) NOT NULL,

        PRICE_WITH_TAX AS (ROUND(PRODUCT_PRICE * 1.01, 2))

);



SQL> INSERT INTO PRODUCTS(PRODUCT_ID, PRODUCT_TYPE, PRODUCT_PRICE)

     VALUES(1, 'A', 99.99);



SQL> SELECT * FROM PRODUCTS;



PRODUCT_ID PRODUCT_TYPE         PRODUCT_PRICE PRICE_WITH_TAX

---------- -------------------- ------------- --------------

         1 A                            99.99         100.99

MySQL虚拟列:

MySQL> CREATE TABLE PRODUCTS (
          PRODUCT_ID INT PRIMARY KEY,
          PRODUCT_TYPE VARCHAR(100) NOT NULL,
          PRODUCT_PRICE NUMERIC(6,2) NOT NULL,
          PRICE_WITH_TAX NUMERIC(6,2) GENERATED ALWAYS AS
             (ROUND(PRODUCT_PRICE * 1.01, 2))
       );

MySQL> INSERT INTO PRODUCTS(PRODUCT_ID, PRODUCT_TYPE, PRODUCT_PRICE)
       VALUES(1, 'A', 99.99);

MySQL> SELECT * FROM PRODUCTS;

+------------+--------------+---------------+----------------+
| PRODUCT_ID | PRODUCT_TYPE | PRODUCT_PRICE | PRICE_WITH_TAX |
+------------+--------------+---------------+----------------+
|          1 | A            |         99.99 |         100.99 |
+------------+--------------+---------------+----------------+

1.5 MySQL和Oracle索引类型差异

1.6 MySQL和Oracle分区差异

1.7 MySQL和Oracle临时表差异

在 Oracle 中,临时表有全局临时表和session级别的临时表之分。在MySQL 中,它们简称为临时表。在这两个平台上,临时表的基本功能是相同的。不过,两者之间存在一些显著差异:

即使在数据库重启之后,

你可能感兴趣的:(面试,学习路线,阿里巴巴,android,前端,后端)