ORMには、主に以下の2点の機能があり、非常に便利なツールである。
| 機能 | 説明 |
|---|---|
| ObjectMapper オブジェクトマッパー | 取得したDBのデータを特定のクラスなどにマッピングし 簡単にオブジェクトとして使えるようにする |
| QueryMapper クエリマッパー | メソッドチェーンのような書き方で、SQL相当の記述を行うことができる |
このうち、チーム開発において「クエリマッパー」の機能だけは気軽に使わないで欲しいということを主張したいと思う。
クエリマッパーを導入することによる不都合
①学習コストが高い
「クエリマッパーを学習するコスト > SQLを学習するコスト」だと筆者は考えている。
これは総合的な学習コストについて述べている。
学習コストが高い理由としては、多くのWebエンジニアにとって
色々なデータベースのSQLを学習するより、色々なクエリマッパーを学習する比率の方が多くなりがちであるからだ。
- データベースは規模や用途によって、ほぼ1,2個に使うものが限定される
- 例:無料かつ大規模になっても耐えうるデータベースは、現状MySQLかPosgreSQL
- DBを参照するシステム構築には様々なプログラミング言語の選択肢が存在する上に、プログラミング言語ごとに複数のORMが存在する
- APIを作るとしても、TypeScript、Java、Ruby、PHP、Go、Pythonなどが選択肢にあがる
- Node環境のORM一つ取っても、TypeORMやPrismaなどの複数の選択肢が存在する
職場やプロジェクトが変わった場合、
使ったことがないDBを触る確率より、使ったことがないプログラミング言語を触る確率のほうが圧倒的に高いというのは
多くのエンジニアが経験していることではないだろうか。
②スイッチングコストが高い
「DBを変えてもSQLの修正が不要であることがORMのメリットだ」という意見があるが、あえて断言する。
そんな意思決定は発生しない。
筆者の経験の中で、データベースだけを別のものに置き換えるというプロジェクトは見たことがない。
一方で、プログラム言語を刷新するというプロジェクトはそこそこ見てきた。
理由はカンタンである。
コストをかけてでもDBを乗り換えたい、という場面はほぼ発生しないからだ。
発生確率が比較的高いプログラム言語の刷新において、ORMも当然ながら刷新対象である。
| 移行対象 | リプレイス頻度 | ORMを使っていた場合の変更方針 |
|---|---|---|
| DBのみ | 極稀 | SQLの方言などはORMが吸収してくれる |
| DB以外のプログラム部分 (APIなど) | まあまあある | 言語が変わるため、ORMそのものの乗り換えが必要 |
このような観点で考えると、むしろSQL文がそのまま書かれていたほうが移植しやすいだろう。
DBをスイッチングするケース
とはいえ、時にはDBをスイッチングするケースは全く発生しないということはない。
ただし、この場合でもクエリマッパーによる恩恵を受けることはない。
DBをスイッチングする目的は
- データ量の増加に適応する
- パフォーマンスを改善する
に集約されると思うが、どちらの場合でもテーブル構成を変えることを余儀なくされる。
なぜなら、これらは「将来的なデータ量の増加を読み切れていない」
もしくは「パフォーマンスに影響があるテーブル構成になっている」という課題に対する解決策だからだ。
テーブル構成の変更を伴う移行作業では、クエリマッパーで書こうとSQLで書こうと修正不可避である。
③簡単にパフォーマンス課題が発生する
クエリマッパーは深く考えずに利用してしまうと、N+1問題のようなパフォーマンス悪化のパターンを引き起こしやすい。
また、「テーブルAとテーブルBをJOINすれば良い」というケースでは、
うっかりしていると内部的に「テーブルCを元にテーブルAとテーブルBをJOIN」してしまうことがある。
これらを回避するためには、結局のところDBの特性やSQLの特性について理解しておく必要があり
「SQLを覚えなくて良い(SQLの学習コストが低い)」ということにはなり得ない。
クエリマッパーが有効なケース
ここまでクエリマッパーについての不都合を伝えてきたが、
クエリマッパーに限らず技術選定における筆者のスタンスは適材適所である。
これまでの不都合が目立たないケース、つまり以下のようなケースでは
むしろクエリマッパーは効果を発揮すると言えるだろう。
- 小規模サービス:パフォーマンス観点でアンチパターンを踏んでも大きな影響にならない
- 個人開発 or 開発者が不変:保守する人はそのクエリマッパーについて詳しい人のため、学習コストがデメリットにならない
- すぐに壊す or 成長を想定しないサービス:DBの移行作業が発生することがありえない
まとめ
ORM利用の際は、クエリマッパーのデメリットについて理解しておくと良い。
また、オブジェクトマッパーの機能についてはデメリットを特に感じてないので
ORMそのものは導入価値が非常に大きいと筆者は考えている。