私のシステム設計の指針は複雑度の分散です。
だからコードの中に複雑なクエリは書きません。
問い合わせのクエリは、何らかの目的があって発行するものなので、JOIN等複数のテーブルが絡む複雑なクエリは、すべてRDBMS側にViewとして持つようにしています。
追記:2009年あたりから、ストアドも対象とするようにしました。
そのためのツールとして型付データセットを利用しています。
そうすることで、コードの中では常に一つのオブジェクト(テーブルであれVIEWであれ)に対して操作をするだけで済むので複雑なクエリが発行される事はありません。
それを実現するために、SQLを直接書かないでクエリを発行するためのフレームワークを作成してあります。
詳しくは書きませんが、型付データセット内で定義されているテーブル単位にラップしているクラスがあり、それに条件を積み上げたオブジェクトをアタッチする事で、様々なクエリを発行するようになっています。
ラップしているクラス自体の定義は前もって用意してあるテーブルにアクセスするための機能を持った抽象クラスを継承してテーブルを指定しているだけなので、数行で済むため作成やメンテナンスの労力はほぼありません。
SQLServerやOracleといった製品毎の差異もフレームワーク側で吸収(.NET Framework2.0にはその機能が実装されていて、そっちに移行しようか悩みました。)し、その中でクエリを自動生成するようにしているため、システムをコーディングするときは、仕様にあうように条件オブジェクトをブロックのように積み上げて、ラップしているクラスにアタッチするだけで良いです。
また、内部でパラメタライズドクエリ(+必要なエスケープ)を作成するためSQLInjectionといった問題も発生しません。
また、ラップするクラス名はテーブルやビューと同じ名前にしてある事と、ビューは目的に応じた名称にしている事から、何が目的でデータにアクセスしているのかが一目瞭然になっています。
この取り組みはもう4年以上続けていますが、
- 複雑なクエリは外(RDBMS側)に目的に応じたVIEWとして持っている
- クエリがコードの中に点在しない
- コード内でデータにアクセスしている部分へのアクセスやコントロールがしやすい
などから昔のシステムでも保守にかける時間が少なくて済んでいます。
また、開発時にコードが複雑になりすぎないため、それ以前に比較すると不具合が少なかったり、不具合が発生してもそれにかける作業時間が少なく済んでいます。
コードの中に複雑なクエリを書いてしまって、修正が大変だとか嘆いている、そこのあなた。
コードにとっての保守フェーズはコードは書いた瞬間から始まっています。
とりあえず複雑なクエリはRDBMSに持ってもらう事でコードの見通しを良くしてみてはいかがでしょうか。