クエリビルダーパターンは本当に幸せをもたらすのか?
Rails やオブジェクト指向の世界では「SQL を大きな塊で書くのはアンチパターンだ」とよく言われます。
代わりに登場するのが クエリビルダーパターン (Query Builder Pattern) や コンポーザブルクエリ (Composable Queries)。
-
小さなメソッドに分割して、
-
必要なときに組み合わせて、
-
再利用性や責務分離を高める。
一見すると DDD (ドメイン駆動設計) や クリーンアーキテクチャ 的な響きもあり、「なんだかカッコいい」感じがしますよね。
現場で感じる違和感
でも、実際にプロジェクトでこの手法を多用すると、こんなことが起きがちです。
1. 可読性はむしろ下がる
Composable Queries の思想は「組み合わせ可能な小さな部品を作る」こと。
でも SQL は最終的に 大きな 1 クエリで結果を返すことが本質 です。
細かく分解すると、最終的にどういう SQL が実行されるのかが見えにくくなり、追うのが大変になります。
DDD で言えば「ユビキタス言語どころか暗号」になりかねません。
2. 再利用性は幻想になりやすい
「共通化したスコープをいろんな機能で使える!」と喜んでも、実際には機能ごとに微妙な差異が出ます。
結局は 無理に再利用したせいで修正コストが爆増 する。
これはクリーンアーキテクチャで言うところの「インターフェースの安定性」を軽視した結果に近いです。
共通化したはずが、むしろ柔軟性を失ってしまうわけです。
3. 責務分離が N+1 を生む
DDD 的に「クエリ生成はドメインの外だからインフラ層に閉じ込めるべきだ!」
そう言って分けすぎた結果、SQL がバラバラになって N+1 問題が発生…。
「アーキテクチャの理想」と「実際の DB パフォーマンス」 の乖離がここにあります。
どれだけクラスをきれいに分けても、DB が何回も叩かれていたら意味がないのです。
シンプルな大きな SQL? それとも JOIN なしのシンプルクエリ?
ここで整理しておきたいのが、「大きな SQL 一発」という言葉の意味です。
-
「SQL を分解して細切れにする」よりは 一発で完結するクエリ の方が良い
-
とはいえ、むやみに JOIN を増やして肥大化した巨大 SQL にするのも危険
本来は JOIN を避けたシンプルな SELECT を複数発行し、アプリ側でマージする方が賢明 です。
この方が責務が明確で、SQL 自体も読みやすい。
ところが、DDD の世界では「N+1 を解決するために JOIN を駆使して巨大な SQL を作る」方向に寄ってしまうことが多いんです。
結局、本来避けたかった“大きな SQL”に回帰しているという、本末転倒な現象が起きています。
まとめ
-
クエリビルダーパターン / コンポーザブルクエリは理論的には美しいが、実装レベルでは複雑性を増やしがち。
-
DDD やクリーンアーキテクチャの理想論に従いすぎると、N+1 を避けるために「巨大 JOIN SQL」を書く羽目になる。
-
本当に賢明なのは JOIN を減らしたシンプルなクエリ を発行し、アプリケーション側でマージする設計。
-
つまり「細切れ SQL」でも「巨大 SQL」でもなく、シンプルで見通しの良いクエリをどう設計するか が鍵になる。
結局、アーキテクチャのスローガンよりも、現場での可読性とパフォーマンス を優先した方が幸せになれます。
登録日:
更新日: