新米武装派フリーランスプログラマ男子(0x1d歳)

DMR REPORT FILE:3 「ゼロからの出発! DB移行ソフトウェアを開発せよ!!」(下)

»

オダ「ほ、本気で言っているのか!? ナカハラ!!」

トリイ「日々のオペレーションでいっぱいいっぱいな上に、これ以上開発案件を抱えるなんて、無茶すぎます!!」

シバタ「僕なんてここに来たばかりで、全然何もわからないんですよ!!!」

カンダ「…………いや、ナカハラさんが考えなしにそんなことを言ったりするとは思えません」

カンダ「……となると、何か『勝算』がある……そうですね?」

ナカハラ「その通りだ」

 ナカハラはホワイトボードへ、赤いマーカーで追記した。

DBの移行対象
・スキーマ(DDL文) 
・データ本体
・制約(PK, FK, UNIQ, CHECK)
・索引
・ビュー  →対象外
・ストアド(PL/SQL) →対象外
・トリガ  →対象外
・SQL文  →対象外

ナカハラ「まずはこの中で、プログラム側の処理となるSQL文については対象から除外する。これは既存プログラム中のSQLをMySQL用に書き換える作業のため、新システムの開発を請け負う開発会社に担当してもらう」

トリイ「プログラム側で利用しているSQLの書き直しは莫大な量ですし、そもそも正しく書き換えられているのかテストすることが、プログラムなしでは困難ですからね」

ナカハラ「うむ。さらにほとんどがSQLで記述されている、ビュー、ストアド、トリガについても、同様に対象外とする」

オダ「PL/SQLなんて実態としてはほとんどプログラムだからな。開発会社へ頼むのが筋かもしれんな……」

トリイ「となるとあとは、スキーマ、データ本体、制約、索引ですか……たしかに結構絞れてきましたね……」

カンダ「ですがナカハラさん、そもそもスキーマや制約、索引といった、DDLが保持している情報を取得することは可能なんでしょうか?」

ナカハラ「良い質問だ、カンダ」

 ナカハラはノートPCの画面をプロジェクタに写すと、ターミナル上でsqlplusの貧弱なCUIを立ち上げた。

ナカハラ「Oracleの場合はUSER_TAB_COLUMNSというディクショナリ・ビューがテーブル名やカラム名、データ型名を保持している。なので、ビュー名をwhere句で絞るだけで移行に必要なスキーマ情報を取得できる」

例:

SQL> CREATE TABLE TEST_TABLE(ID NUMBER(5) PRIMARY KEY, NAME VARCHAR(20) );

表が作成されました。

SQL> DESC TEST_TABLE;
 名前                                    NULL?    型
 ----------------------------------------- -------- ----------------------------
 ID                    NOT NULL NUMBER(5)
 NAME                           VARCHAR2(20)

SQL> SELECT TABLE_NAME, COLUMN_NAME, DATA_TYPE, DATA_LENGTH
  2  FROM USER_TAB_COLUMNS WHERE TABLE_NAME = 'TEST_TABLE';

TABLE_NAME
--------------------------------------------------------------------------------
COLUMN_NAME
--------------------------------------------------------------------------------
DATA_TYPE
--------------------------------------------------------------------------------
DATA_LENGTH
-----------
TEST_TABLE
ID
NUMBER
     22


TABLE_NAME
--------------------------------------------------------------------------------
COLUMN_NAME
--------------------------------------------------------------------------------
DATA_TYPE
--------------------------------------------------------------------------------
DATA_LENGTH
-----------
TEST_TABLE
NAME
VARCHAR2
     20

ナカハラ「同様に制約や索引についても、SQLだけで取得できる」

カンダ「なるほど……」

ナカハラ「ちなみに、この『SQLだけでDDLの情報が取得できる』機能はRDBMSの機能として標準化されつつあるな。MySQLでのshow tablesコマンドやdescコマンド相当をSQLで代替することも容易だ」

トリイ「確かに、テーブル一覧をselect * from cat;で取得するなんてのは基本中の基本ですからね……」

オダ「だがナカハラ、データ本体はどうする!? 当然OracleからMySQLへはexp/impやData Pump、もしくはmysqldumpユーティリティを使ってデータをやりとりすることはできないぞ!!」

ナカハラ「フフフ……そこも考えてある」

Niyar_nakaharai

ナカハラ「OracleとMySQLのダンプデータの間に互換性はない……」

ナカハラ「だが、『両方で読み込み可能なデータ形式』で出力したとしたら、どうだ?」

シバタ「ど、どういうことですか?」

ナカハラ「簡単なことさ。『CSV』で出力するんだよ」

Csv

カンダ「CSV!! その手がありましたか!!」

トリイ「たしかにCSVなら、ほとんどのRDBMSでスキーマへ直接流し込むことが可能だ!」

ナカハラ「もちろん、通常のCSVではカンマや改行文字がデータ本文中に含まれた場合に問題が起きてしまう」

ナカハラ「よって、利用するのはこれらの区切り文字を適宜別の形式――例えばタブ文字や特定の文字列に変換したフォーマット――いわば『中間データ形式』とでも呼ぶべきものになるが、基本的な考え方は変わらない」

 シバタがおずおずと手を挙げた。

シバタ「すみません。ですが、その『CSV』はどうやって作るのですか?」

ナカハラ「これも簡単だ。基本的には既存のデータをすべて移行すればいいのだから、『SELECT *』で抜いてきたものをすべてファイルに出力すればいい。これくらいならドライバさえあれば、スクリプト言語などを用いて容易に実装可能だろう」

31

シバタ「DBに接続して『SELECT *』で抜いてきたデータを、カラム別に区切り文字を入れて区切り、レコードごとに改行文字列を入れてファイル出力する……」

シバタ「うん、たしかにこれくらいのプログラムなら、僕でも簡単に実装できそうです!!」

ナカハラ「これら一連の移行作業を図にすると、こうなる」

 ナカハラはさらさらとホワイトボードに記述した。

32_2

オダ「なんてこった……こんなにも単純になるのか……」

シバタ「これなら僕でも理解できます!!」

カンダ「『データベース移行』と今までは漠然と難しく考えていましたが、ここまで掘り下げれば……」

トリイ「これだけならなんとか、業務の合間に実装することもできそうですね……」

ナカハラ「どうだ? この方法なら『内製』も十分に可能じゃないか?」

オダ「ああ! これならやれそうだな!!」

カンダ「進めていくうちに細かい問題が出てくる可能性はありますが、大方針さえ定まっていれば個別に対応できます!!」

トリイ「コスト的にも問題なさそうです!!」

シバタ「なんだかやる気がでてきました!!」

オダ「ったく、こいつはほんとに調子いい野郎だぜ!!」

 活気づくシバタに、オダがアームロックをかける。

シバタ「アイタタタ……」

カンダ「オダさん、危ないですから暴れないでくださいよ……」

トリイ「それ以上よくない」

 深夜の会議室に、一転して大きな笑い声が響く。

 ナカハラは皆の明るい表情にしばし目を細めたが、すぐに真剣な表情でチームメンバーへと向かった。

ナカハラ「では、みんな……」

Aratamete

Oh

つづく

 

※この物語は事実をもとにしたフィクションです。
実在の人物、団体、商品とは一切関係ありません※
Comment(3)

コメント

Aqueth

ちょいと疑問なったが、
CREATE文を抽出する方法とか、
データをCSVで出力するスクリプトって、
krown検索すれば見つからなかったっけ?

terukizm

ma2riderさんのは多分Oracle用のDDLを作るツールなので、他のDB用のSQLは吐けないかと。

CSVで吐くのも別に難しくないので、一時間もあれば書けると思います。
ただバッドノウハウがすごいありまして……そのあたりがかければよいのですが……

コメントを投稿する