RailsというかActiveRecordというか、今どきのモダンなORマッパーには、migrationという仕組みがある。
データベースのテーブル定義を、sql文で作るのではなく、プログラミング言語で定義できる。select や updateがRubyでできるなら、create tableやalter tableもRubyで書いちゃえばいいじゃないという発想。しかも履歴管理ができるから、戻すことも可能。これはユートピア。
しかしながらどうも言うほど登場シーンがない。以下のようなケース。
既にテーブルがある
100%Rails完結するならいいんだけど、Javaのシステムが使ってるテーブルの管理画面をRailsで作るとかって、全然ありえる話。その場合って、もうmigration が要らないのです。「有るべき姿」ではないのだが、RDBが事実上のインターフェースファイルみたいになって、サブシステム同士を結びつけているケースもある。ActiveRecordeのモデルの裏方ではなく、もはやRDBがインターフェース。思想としては間違いなんだろうけど、RailsとSQLのどっちが「世界共通言語?」って問いに対しては、SQLが勝ってしまう。
デプロイのタイミングと、alter table のタイミングが違う
Rubyのソースで一括管理すると、ソースのリリースとテーブル定義の変更が、「せーの」でできて、超美しいように見える。だけど本番ではなかなかそういうことしない。DBの定義ってソースのリリースよりも前に、テーブル定義をかえーの、ちょっとしたデータ変換をおこないーの、旧ソースでも新ソースでもどっちでも行ける状態にして、新ソースをドーンとリリースという形が多い。
結局ゴリゴリに直でDBをメンテすることになる。
テーブル定義は地味にエンジン依存が激しい
「utf8mb4 migration」 とかでググるといっぱい事例が出てくるんだけど、DBが定義する新しい目(といってもかなり前から実装されているmysqlの型)が、migratiion には長らく対応していなかった。ORマッパーそのものがDBエンジン依存を排除できるのがいいのところなのだが、実際には4バイトUTF8もネット上ではちらほら居ている。いわゆるUNICODE絵文字が保存したかったら、migration 使えない。