#15 schema migration

2011-12-15

マイグレーションというものについて私の考えをまとめてみたいと思います。

まず、マイグレーションの定義ですよね。
マイグレーションとはhttp://www.sophia-it.com/content/%E3%83%9E%E3%82%A4%E3%82%B0%E3%83%AC%E3%83%BC%E3%82%B7%E3%83%A7%E3%83%B3
とかいろいろな意味があるんですが、ORMだったりdatabase周りで語られる場合は、
schemaのバージョン管理的な意味合いで良いと思います。

例えばMySQLで例を挙げますと、

CREATE TABLE `user` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(10) DEFAULT NULL,
  PRIMARY KEY (`id`),
  KEY `name_idx` (`name`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8

こういったテーブルがあったとして、これに年齢を表すageカラムがついかされるとします。
その場合MySQLだと

ALTER TABLE user ADD COLUMN age int(10) UNSIGNED NOT NULL DEFAULT 0 AFTER name;

などと実行してカラムを追加することになります。
そうすると、

mysql> SHOW CREATE TABLE user\G
*************************** 1. row ***************************
       Table: user
Create Table: CREATE TABLE `user` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(10) DEFAULT NULL,
  `age` int(10) unsigned NOT NULL DEFAULT '0',
  PRIMARY KEY (`id`),
  KEY `name_idx` (`name`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8
1 row in set (0.00 sec)

このようになるわけですね。

こういった新しいカラムの追加をORMでカバーするかどうかです。

たとえばDBICではある程度カバーしてくれますし、それを有効に使って開発を進めている人達を知っています。

ただ個人的にはこういった管理はORMではない別の仕組みでカバーするべきだと考えます。
というのも、ORMが扱うであろうCRUD操作とDDLは別物として捉えるのが良いと考えるからです。

DDL操作なんてそんなに頻繁にしないですよね?
一日に何十回、何百回と操作しますかね?普通はないんじゃないでしょうか?

さらに、databaseの種類はかなりの数あります。

MySQL

SQLite

PostgreSQL

Oracle

MSSQL

DB2

etc..

全てのdatabaseでDDLの操作方法が一緒というわけではないため、もしORMがそれをカバーしようとしたら
本来の役割とはちがうところで無理に頑張る必要がでてしまいます。

いやでもDBICできてるよ!と思う人もいると思いますが、DBICでできるのは基本的なDDL操作だけで
各RDBMSの独自の機能までカバーしているわけではありません。

それに私は現在のところMySQLを使った開発しかしていないためOracleとかMSSQLとか他のRDBMSのことに詳しくないので
そこまで面倒みきれません。


ではマイグレーションはどうすればいいのでしょうか。

今まで私はベースとなるcreate文とそれ以降に実行したalter文なんかをsvnやgitなどで管理し、
restoreする時に必要になった場合なんかはそれを元に再現したりしてましたし、
通常serviceのdatabaseはbackupされているはずなのでそこから持ってきたりなんかもしてました。
複数人で開発していてカラムの追加だったりテーブルの追加があるときはコミュニケーションで解決できなかったことがないので
そこまで危機感がないのかもしれませんがどうでしょう。


ある程度大きなプロジェクトになってくると仕組みで管理したいことがあるのはあるでしょう。
今のところはSQL::Translatorをつかえば大体のことはできます。
DBICのバックでも使われています。

たださっきもいったようにRDBMSのそれぞれの方言をカバーしきれているわけではないので、
個人的には各RDBMSに特化したマイグレーションの仕組みを作ったらいいんじゃないかなと思っています。


ORMのコミュニティーを活発にして開発者をふやしてORMでマイグレーションの仕組みを頑張っていれるより
特定のORMのに特化せず、利用するRDBMSに特化した仕組みを作るほうが将来があると思ってます。


自分の周りではMySQLのマイグレーションについて色々意見がでてるので
もしかするとそう遠くない将来に良い仕組みが出てくるかもしれませんね。
#MySQL限定ですが


だらだらと長くなってきたのでまとめると、


RDBMS毎に方言があるんだから、ORMでマイグレーションを管理するのはやりすぎ。
人生はそう長くないのでRDBMSに特化したマイグレーションの仕組みを構築し、他に無駄に依存しない仕組みを考えたほうが将来がある。
と思っています。


みなさんの意見はいかがでしょうか?


明日はTengの使い方に戻ってトランザクションのかけ方について紹介したいと思います