ナスです。

オンプレ Oracle から RDS Oracle に移行する話が意外と多いです。Aurora への移行とかはどれくらい行われているのかはわかりませんが、少なくとも私はまだほとんど聞いたことがありません…まだまだこれからですね。

ただ、Oracle から RDS Oracle に移行するだけなのに、わりとすんなりいかないもんです。なんとなく多いと思っているのは、DMS で移行後のデータ型が変換されてしまって悩むパターンですね。今回は数値データ型(NUMBER)を例に、どのように変換されてしまうのか、またどうやって対処すればいいのかをご紹介します。

DMS で NUMBER はどう変換されるのか

DMS で RDS Oracle へ移行した後によく気になるのは、数値が NUMBER(38,10) データ型になってしまうパターンでしょうか。これはトラブルシューティングドキュメントの「NUMBER のデータ型が誤って解釈される」に書かれています。

AWS Database Migration Service を使用してデータを移行する場合の問題のトラブルシューティングについて説明します。

docs.aws.amazon.com

例えば、移行元は NUMBER なのに、移行先では NUMBER(38,10) になっている、という感じです。なんで勝手に精度とスケールの数値がつくんだよ!って最初は思いました。

実際にテストしてみました。↓は移行元のテーブルです。

SQL> desc tbl1;
 Name                      Null?    Type
 ----------------------------------------- -------- ----------------------------
 COL1                           NUMBER
 COL2                           VARCHAR2(100)

↓は移行先のテーブルです。

SQL> desc tbl1;
 Name                      Null?    Type
 ----------------------------------------- -------- ----------------------------
 COL1                           NUMBER(38,10)
 COL2                           VARCHAR2(100)

そもそもなんでそんな風に変換されるのか

DMS を使うとどのデータ型がどのように変換されるのか、それはドキュメントに記載があります。

移行元のデータ型と DMS データ型のマッピング

AWS Database Migration Service でサポートされている Oracle のソースデータ型について説明します。

docs.aws.amazon.com

DMS データ型と移行先のデータ型のマッピング

AWS Database Migration Service を使用したデータ移行のターゲットとして Oracle データベースを使用する場合の Oracle のデータ型について説明します。

docs.aws.amazon.com

まず今回の例でいくと、移行元の NUMBER は精度もスケールも指定されていないので、Oracle 公式ドキュメントによると精度38、スケール0になるようです (NUMBER(38) ってことですね) 。
Oracleデータ型

続いて、移行元のデータ型と DMS データ型のマッピングをみると、「精度がスケール以上の場合、NUMERIC を使用します。」とありますので、DMS では NUMERIC になります。

さらに、DMS データ型と移行先のデータ型のマッピングをみると、DMS の NUMERIC は 移行先 RDS Oracle では NUMBER (p,s) になることになっています。精度とスケールは書かれていませんね?
そして最後にみるのが、下の追加属性の項目です。NUMBER の精度とスケールのデフォルト値が書かれています。

DMS での追加の接続属性の使用

このセクションでは、AWS DMS の追加の接続属性について説明します。

docs.aws.amazon.com

Number スケールを指定します。最大 38 のスケールを選択するか、FLOAT を選択できます。デフォルトでは、NUMBER データ型が精度 38、スケール 10 に変換されます。

なるほど、だから移行元の NUMBER は、移行先では NUMBER(38,10) になってしまうんですね。

これは困る!どうやって同じ型にすればいいのか?

今回の例では、DMS での追加の接続属性の使用のドキュメントの通り、DMS の移行元のエンドポイント設定で、追加の接続属性に numberDataTypeScale=0 を追記すれば OK です。

まず、DMS エンドポイント設定で、移行元のエンドポイントを選択して変更ボタンを押します。

アドバンストの箇所を開くと、追加の接続属性の欄があるので、下図のように追記します。

この後、再度移行タスクを実行すると、移行先のデータ型は下記の通り NUMBER(38) になります。

SQL> desc tbl1;
 Name                      Null?    Type
 ----------------------------------------- -------- ----------------------------
 COL1                           NUMBER(38)
 COL2                           VARCHAR2(100)

データ型のマッピングを AWS ドキュメントで確認すれば、どのデータ型がどのように変換されるのかがわかるので、うまくいかなかった時はもう一度読み返してみましょう。きちんとたどればきっと何かわかりますよ。

元記事はこちら

DMS で RDS Oracle に移行する際に引っ掛かりがちなポイント [cloudpack OSAKA blog]