#O/Rマッピングは百害あって一利なし!
O/Rマッピング(Object-relational mapping)について、Wikipediaには以下のように書かれています。
データベースとオブジェクト指向プログラミング言語の間の非互換なデータを変換するプログラミング技法である。
O/Rマッピングを実現する仕組みを、O/Rマッパーと言います。(両者を区別しなくても私が言いたいことは伝わると思いますので、ORMと統一して記述します)(また、個人的な理由で、プログラミング初学者向けに語りかける口調にしていますが、初心者向けの記事というわけではありません)
最近はWEBアプリ開発をするにあたって、WEBフレームワークに標準で何らかのORMが組み込まれていることが多いため、その存在を知らない人はまずいないでしょう。
私も何度かORMと向き合ってきましたが、そうこうしているうちに気がつきました。
ORMはめんどうくさい!
…ってことに。
みんな黙って使っているから、私も黙って「便利♪」と言って使おう。
右向け右。左向け左。まわれ右、1、2、止まれ…まあ、そうやって隊列をくずさず進もう!と思っていましたが、もう限界です。
オレオレORMの瘴気にヤられて愚痴りたくなった衝動を抑え、世の中にあるORMを少し調べてみました。
でも、もやもやは晴れませんでした。
(現在の)私の結論は「O/Rマッパーは百害あって一利なし!」です。
…そうは言っても、オブジェクト原理主義者は納得しないでしょう。
彼らには何を言っても無駄かもしれませんが…世に言うORMのデメリットとメリットをならべて、個人的な見解を述べておきたいと思います。
##ORMのメリット(?)
###SQLを知らなくてもCRUD処理が書ける(?)
とあるプログラミングスクールの「Ruby On Rails」学習教材を眺めていて驚きました。
「ActiveRecordは、SQLという難しい言語を学ばなくても、データベース操作ができる便利な仕組みです」そんなトーンの記述がしれっと書かれていました。
google先生で調べてみたところ、Qiitaでも同じことを言っている人がいます。
「SQLはできませんがORMは使えます」と言っている人もいます。
「ORMがあるからSQL知らなくてもOK」と言い切っている人もいます。
おじさんびっくり!
でも、これはまずいです。
内部的にどんなSQLが発行されている知らないと、ORMという道具に振り回されていることになります。
チューニングを丁寧に行うならばなおのこと、最適化されたSQL文を扱えるようになりたいものです。
例えばですが、N+1問題などを考えている時点で、テーブルのカーディナリティは無視できませんよね。それならば、はじめからRDBMSとSQLを学ぶほうが、遠回りなようでいて、長い目で見れば近道です。
###インピーダンス・ミスマッチの解消(?)
そもそもORMはインピーダンス ミスマッチ(impedance mismatch)の解消を図るための思想だと言われています。O/Rマッパーは「違うシステム」「異なるパラダイム」のものを、柔軟にくっつけようとする思想です。
でも、これって必須の取り組みですか?
SQLとテーブル構造が分かっているならば、言語に合わせてバラバラに展開し直すだけで、手間が増えている気がします。
(プログラミング言語によるかもしれませんが)必ずオブジェクト指向プログラミングなるものをしなければならない理由はないはずなので、配列データなどにして処理するほうが流れとしても、ずっとスマートだと思います。
###DBとAPPの結合度を弱める(?)
WEBアプリのCRUD機能の数だけSQL文を用意した方が素早く開発ができます。
…というか、ビジネスロジックのみならずプレゼンテーションロジックの処理をSQLで極力してしまった方が処理も速いです。デキる先輩ITエンジニアは、口を揃えて「SQLのみでやれ」と言う人が多い気がします。
これをDBとAPPの密結合だと批判するのは簡単ですが、個人的にはORMだから修正点が減ることよりも、ORMだから修正点が増えることのほうが、ずっと多い気がします。(特に未知のシステム改修で、ORM内をいじらざるを得ない時は、最悪です)
RDB製品とNoSQLの互換性があるORMライブラリもあるかもしれませんが、詳しく知りません。そんな便利なものがあるなら、ぜひ教えてください。どちらにせよ「これは便利!」と思ったORMに出会ったことがありません。
…というわけで、DBと密結合したコーディングでOK!
一人で小規模な開発をする時は、割り切ってコードを書いています。
※ 結合度の問題はまた後でもふれます。
###管理ツールなどによりスキーマ管理しやすい(?)
スキーマ管理が便利なのは、ORMがもたらす直接的なメリットではありません。それはスキーマ管理ツールが優れていただけの話です。
###データベース接続やエラー処理を簡単にする?
これも、ORMのメリットというより、DB操作ライブラリがもたらしてくれる機能でしょう。
###SQLの方言を気にしなくてよい(?)
SQLのCRUDを直書きする=SQLの方言を気にしなければならない状況とは、データベース製品をリプレイスする時に問題になると思います。しかし、データベース製品を途中でリプレイスする事案にあまり遭遇したことがありません。
これは、先にもふれた、DBとプログラムの密結合と本質的に同じ問題です。
でも周りのエンジニアに聞いても、そんなDBを交換するプロジェクトに、アサインしたことがないと言います。
DB2、SQLServer、OracleなどのRDBをOSS-DBに変更するなんて話は、もしかしたら、あるのかもしれませんが、はじめから有償のRDB使っている時点で何かが間違っている気がします。また、そんなことにエンジニアのリソースを使うより、ライセンス料を支払ったほうが安いはず。
性能を上げるためならば、製品のリプレイスよりマシンのスペックを上げるとか、他の手段による方がよい場合が多いはず。
個人的にMySQLからPostgreSQLなどへ、エディタの置換処理で方言を変換して移行したことはありますが、SQL言語の方言吸収を手動でやろうが、O/Rマッパーのライブラリをまるっと変更しようが(その時はO/Mマッパーが方言を吸収できなかった)、全面的にテストする時間的なコストのほうが大幅にかかります。
したがって、O/Rマッパーを使ったときと使わなかった時のコストはあまり変わりません。
(RDBMS)ミドルウェアとアプリケーションの疎結合性を蔑ろにしてもよいという気はありませんが、そこを重要視するくらいならば、他に気にすべきことがあるのでは?と経験的に思います。
###プログラム内のデータアクセスを統一する(?)
「ORMで書けない場合はSQLを書く必要があります」としれっと言う人がいますが、それはORMのメリットである疎結合性を蔑ろにしていると思うのですが…そのへんの矛盾をORM好きなオブジェクト指向原理主義者は否定しないんでしょうか?
※余談かもしれませんが、テーブル名とカラム名が定数化されているオレオレORMも見たいことがありますが、カラム名はともかくテーブル名って変わりますか???」テーブルはオブジェクトであり、オブジェクト名が変わる=データ構造が変わることで、ふつうならありえません。そういうことがあるとすればオブジェクト名変更ではなく、オブジェクト削除か新規作成になるはず。オブジェクトやオブジェクト名は普遍的なものなので、まず変わりません。
ORMのメリット(!)
一切なし!
※1行でデータがとれるので記述を減らせるとか、SQLを知らなくてもデータがとれるとか、そういうのはただのデータ取得をメソッドにより抽象化しただけで、イコールORMを意味しません。
結論(!)
はじめから結論ありきで恐縮ですが、やはり「O/Rマッパーは百害あって一利なし!」
さいごに
…とは言っても、世の中はORMだらけなので無視はできません。でも、WEBアプリ開発の初学者は、ORMのメソッドでデータベース操作をしてもいいですが、後でSQLはきちんと学びましょう。SQL操作が分からずに困ることが、後でたぶんきます。
SQLは可読性が高いわけでも処理が速いわけでもありません。
何にでも一長一短はありますが、今後はもっとよいパラダイムが出てくることを願って(または当事者として、解決に汗を流して問題に取り組むにせよ)SQLをうまく使いこなしましょう。