OracleからMySQLへのテーブル定義（DDL）の移行

OracleからMySQLにテーブル定義をまとめて移行する方法です。

## 経緯など
開発環境以上はOracle。
そこそこ制約が厳しいので、個々の開発の段階で、より自由に操作できるDB環境を整えるため。
移行対象のテーブルは650以上。
OracleとMySQLでは、構文が異なる部分があるため、SQLines SQL Converter Tool（以下、Sqlines）というフリーのコンバーターを使って、DDL変換することにしました。

## 環境と前提条件

- OS（ローカルPC）：Windows10
- OS（MySQLインストール先）：CentOS6.8
- 移行元DB：Oracle Database 12c
- 移行先DB：MySQL8.0（database（Oracleでいうところのschema）は作成済とする）

## 使用ツール、方法
- OracleからのDDLエクスポート：SQL Developer
- Oracle → MySQLへDDLコンバート：Sqlines
- インポートファイルの移動（ローカルPC → MySQLインストール先）：WinSCP
- MySQLへのDDLインポート：Linuxコマンド

## 作業イメージ
作業イメージは以下の通り。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/356958/f839f01c-432b-3e58-4a5b-e3c4c801d991.png)


## 手順

### 1. 事前準備
使用するツールをダウンロード & インストールしておきます。

### 1-1. SQL Developerのダウンロード ～ 接続設定
[Oracle SQL Developer ダウンロード](https://www.oracle.com/technetwork/jp/developer-tools/sql-developer/downloads/index.html)より、SQL Developerをダウンロードし、移行元DB(Oracle）に接続できるようにしておきます。
詳細な手順は、[SQL Developerの使い方～ダウンロード、インストール、DB接続、SQL実行](https://blogs.oracle.com/oracle4engineer/sql-developerdbsql)をご覧ください。


### 1-2. Sqlinesのダウンロード ～ 解凍
[Sqlines](http://www.sqlines.com/)より、Sqlinesをダウンロードし、解凍しておきます。
手順は以下の通り。
(1)[Sqlines](http://www.sqlines.com/)にアクセスし、画面右端の「Migration to MySQL」下の「Oracle to MySQL」をクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/356958/6cf9d2cf-3d47-c42e-d39e-61fdb7335703.png)

(2)「SQLines SQL Converter Tool」下の「Desktop Version」をクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/356958/ff56ac69-8141-9e04-e7ce-b71c2520bed4.png)

(3)Windows版の最新版をクリックしてダウンロード。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/356958/d194d600-b0ae-a18e-077a-8c4e4502a1dd.png)

(4)ローカルPCの任意の場所に展開します。フォルダの中は以下のようになっています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/356958/1ac5ce9c-c80d-cf98-6111-f3342807bb19.png)

※現時点で、のMySQLの対応バージョンは5系ですが、インポート後にアップグレードするため、問題ない認識です。

### 1-3. WinSCPのダウンロード ～ 接続設定
[WinSCPオフィシャルサイト](https://winscp.net/eng/download.php)より、WinSCPをDLし、移行先DB（MySQL）の入った環境に接続できるようにしておきます。
詳細な手順は、[WinSCP インストールから基本的の使い方](https://proengineer.internous.co.jp/content/columnfeature/9414)をご覧ください。

### 2. テーブル定義（DDL）エクスポート from Oracle
Oracleからテーブル定義（DDL）をエクスポートします。

(1) SQL Developerを起動し、「ツール」タブ（①） > 「データベース・エクスポート」をクリックします（②）。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/356958/ed2bd56a-88ce-5abf-7604-f968f44df840.png)

(2)エクスポート・ウィザードが立ち上がったら、接続DBを選択します（①）。
DDLのエクスポート欄の「スキーマの表示」のチェックをはず
今回はDDLのみが対象なので、「データのエクスポート」（③）のチェックを外しておきます。
移行元DB（Oracle）に合わせたエンコーディングを選択し（③）、「参照」を押下して、エクスポート先とファイル名を指定し（④）、「次」をクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/356958/52aceb9a-0d40-cc3e-6ef5-a96c0e28fd0b.png)


(3)「エクスポートするタイプ」の選択です。デフォルトでは、「標準オブジェクト型」のすべてにチェックが入っていますが、「表」のみにし（①）、「次」（②）をクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/356958/36c7b3f8-df23-c2b6-e736-3d6b0203fe74.png)

(4)「オブジェクトの指定」画面に切り替わったら、「増やす」をクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/356958/4c6b09e3-02cd-b383-419b-1b7aa052b983.png)

(5)対象のスキーマを選択し（①）、「参照」をクリック（②）。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/356958/47ad1bae-bb86-e869-5dde-596189f73df9.png)

(6)対象のテーブルを確認し（①）、「>>」をクリック。
※一部のテーブルのみ移行する場合は、対象のテーブルを選択し（複数選択できます）、「>」をクリックしてください。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/356958/dbe5ee53-7804-56e4-55be-b9a7c6097887.png)

(7)内容を確認し（①）、「次」をクリック（②）。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/356958/fd438332-cee2-af2a-46a3-0059c0ac22df.png)

(8)「エクスポートのサマリー」画面に移動したら、内容を確認し、「終了」をクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/356958/e2efb355-bbbe-9579-b5a2-6642972f326c.png)

(9)DDLのエクスポートが始まります。量が多い場合は、「バックグラウンドで実行」してもよいでしょう。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/356958/dadad9df-cfce-5f78-b841-7f8f6b94b8db.png)
※650強のテーブルのエクスポートで5分ほどかかりました。

(10)終了すると、エクスポートされたファイルが開くので内容を確認します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/356958/bbd1b5e5-2ff5-c073-8e13-f954d02a5f32.png)

※量が多い場合は以下のメッセージが出て開きませんが、指定した場所にはエクスポートされているのでご安心を。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/356958/8f8cc0d6-e11d-c839-44c9-5ee8e1be46c7.png)

### 3. テーブル定義（DDL）コンバート from Oracle to MySQL
エクスポートされたDDLはOracle用なので、MySQL用にコンバート（変換）します。

(1)解凍したSqlinesのフォルダを開き、「sqlinesw.exe」をダブルクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/356958/7bf3cb6d-42b9-1270-43b1-ac82e6b6b286.png)

(2)Sourceの「Database」で「Oracle」を選択し（①）、「Input SQL Scripts」でエクスポートしたファイルを入力します（②）。
Targetの「Database」で「MySQL」を選択し（③）、「Output SQL Scripts」で任意のファイル名を入力し、「Convert」（⑤）をクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/356958/565a109f-fb57-c7a7-4abb-f943c7212727.png)
※②, ④では別ウィンドウが開きますが、フォルダの選択までしかできないので、ファイル名は手動で入力してください。

(3)Convertが実行されるとログが出ます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/356958/af80dab2-a866-829f-caf2-0a94ba0a5e33.png)

※こちらは即完了！1秒かかったか、かからなかったかというレベル。

(4)(2)の④「Output SQL Scripts」で指定した格納先にコンバートされてできたファイル（以下、インポートファイル）が存在することを確認します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/356958/fe515964-137c-e61f-f5d5-38fd4246db6f.png)

### 4. テーブル定義（DDL）インポート to MySQL
(1)WinSCPで手順3でできたインポートファイルを移行先DB（MySQL）の入ったサーバの任意のディレクトリにコピーします。

(2)移行先DB（MySQL）の入ったサーバにrootユーザーでログインし、MySQLが起動していることを確認します。

```
# service mysqld status
```

(3)でインポートファイルを配置したディレクトリに移動します。
/home/hogeに配置した場合は以下の通り。

```
# cd /home/hoge
```

(3)以下のコマンドを実行し、DDLをインポートします。

```
# mysql -u root -p -f < インポートファイル名
```

(4)終了したらMySQLをアップグレード＆再起動します。

```
# service mysqld restart --upgrade=FORCE
```

※「mysql_upgrade」はMySQL8ではdeprecated（非推奨）なので、代わりに「--upgrade=FORCE」を使います。


(5)MySQLにログインし、テーブルがインポートされていることを確認します（以下、rootでログインの場合）。

```
# mysql -u root -p 
# use 対象のデータベース名;
# show tables;
```

## 終わりに
SQL ServerやPostgres SQLなど → MySQLの移行、MySQL → Oracleの移行ツールは検索すればわりとすぐに出てくるのですが、Oracle → MySQLは一筋縄ではいかず、方法探しと選定だけでも丸1日以上かかりました。
（考えてみれば同じOracle社管轄で高価なOracle Database → 安価なMySQLの移行方法がやたら出回るわけないのですが。）

MySQLインポート時にエラーが出ることがありますが、そのトラブルシューティングについては、
[OracleからMySQLへのテーブル定義（DDL）の移行時のトラブルシューティング | Qiita](https://qiita.com/C_HERO/items/904b7c5d195006118a54)
に書きましたので、そちらもご覧ください。
（エラー発生分以外はオプション-fにより、インポートされるので、その辺はご安心を）。

Sqlinesは、他DB → 他DBへのコンバートもできるようなので（例：SQL Server → Postgres SQL）機会があればやってみたいです。

## 参考
以下を参考にさせていただきました！ありがとうございました！

- [OracleからMySQLへデータ移行したお話 | Qiita](https://qiita.com/rirne/items/d973b6678981e46326a4)
- [OracleからMySQLへの「オブジェクト移行」に向けた3つのステップ | @IT](https://www.atmarkit.co.jp/ait/articles/1701/10/news017.html)
- [【番外編】MySqlの基礎を学ぶ2、Error Code: 1449 The user specified as a definerのエラーを解決させる | 毎日テキストマイニング](https://dailytextmining.hatenablog.com/entry/2018/06/30/203132)
- [MySQLでDB移行する時はmysql_upgradeを行おう | SEEDS Creators Blog](https://www.seeds-std.co.jp/blog/creators/2012-11-23-205450/)
- [MySQL 8で、mysql_upgradeがdeprecatedになった | Qiita](https://qiita.com/tana6/items/c925ff2648e395c004ac)