コードに保存されているSQLクエリを整理する最良の方法は?(またはあなたがすべきですか?)[閉じた]


13

SQLクエリで散らかったコードのページを見たときにイライラするのは私だけではないはずです。ActiveRecordおよびその他のORMパターンは、プロジェクトで使用される大量のSQLを軽減するのに役立ちますが、複雑なクエリの多くの場合、SQLの使用は避けられないようです。

SQLクエリを他のコードと一緒に(または外部的に)整理して、どこにでも散らばらないようにする方法についての意見を探していますか?1つの明白なアイデアはビューの使用ですが、多くの場合、ビューは複数の大きなインデックス付きテーブルなどを処理する際にパフォーマンスの問題の原因になる可能性があります。

編集1-あなたはすでにモデルレイヤーに分離されていると仮定しています


3
この質問はここでは間違いなく適切です-コード編成:「「なぜ」と「どのように」を説明する回答を促します。」そして被験者のデザインパターン'と(から「アーキテクチャ」であるよくあるご質問
マイケル・K

1
これと同じ質問をしようとしていました。ここにもっと答えがあればいいのに。
マイケルクリストフィック

回答:


10

私にとって、SQLはビジネスロジックコードの基本的な部分(多くの場合、大部分)です。返されたデータを操作するコードからそれを分離しようとすると、コードの理解性と保守性のバランスが崩れやすくなります。

私が見ると、データの読み取り、データの処理、データの書き込み、データの検索などはすべて同様の操作であり、同じ場所に保管するのが最適です。

クエリを使用した作業の重複を感じ始めたら、おそらくデータベースビューまたはデータベースアクセスのその側面をカプセル化できるオブジェクトが必要になります。

別のヒントは、実際に適切なデータベースクエリメソッドを使用することです。私が書いているソフトウェア(PostgreSQL、MySQL、SQL Server)では、クエリ操作の大部分が単一のコードステートメントとして実行されることを保証しています。

GetValue(SQL, [transaction], [array_of_params])
GetRow(SQL, [transaction], [array_of_params])
GetRowList(SQL, [transaction], [array_of_params])
GetValueList(SQL, [transaction], [array_of_params])
Execute(SQL, [transaction], [array_of_params])

これらは(大体)私の「接続オブジェクト」の一部であることを保証するメイン関数呼び出しです。それは言語、実際に実装するものに依存しますが、私のポイントはそれを本当に、本当にシンプルで、痛みのないものにすることです。

要約すると、 SQLをプログラミングのネイティブ部分として扱い、抽象化のために抽象化しないでください。


1
素晴らしい答え。多分私はただ後ろに戻って、コードの中に散らばるだけでなく、コードの一部としてSQLを見始める必要があります。
jellyfishtree

1
「抽象化のために抽象化しない」-良い点。より理解しやすいコードのために要約。
ジェイソンベイカー

「もう1つのヒントは、実際に適切なデータベースクエリメソッドを使用することです」:私は間違いなく同意します。ビジネスロジックが変更されたときにコードを変更する場所が1つしかない場合に役立ちます。
マイケルK

1
SQLはどこに配置しますか?それはアプリケーションにコンパイルされ、上記の方法を使用して送信されますか?
ジョニー14年

Jason Bakerの回答「OPの巨大なSQLクエリをじっと見つめている」に対するOPのコメントに基づいて、これはSQLテキストの大きなブロックを読み取る問題にどのように対処しますか?
ジェフ14

0

一般的に、個別のモデルレイヤーを用意することが最善の方法です。これを設計する方法を提供するエンタープライズ設計パターンがいくつかあります。


申し訳ありませんが、私はもっと具体的にする必要がありました...私はすでにそれらをモデル層に分離していると仮定しています。ただし、モデルレイヤーは、SQLコードによってかなり分散する可能性があります。たぶんこれは避けられないでしょう。モデルコードでフリーク私を多分これは自社工場や何かに分離されなければならない...いくつかのロジックに基づいて、「SQLクエリを構築する」というコードであることを他の事...
jellyfishtree

2
@jellyfishtree-問題が何であるか理解できません。つまり、モデルレイヤーが多くのモデルコードで終わるのではないかと心配していますか?
ジェイソンベイカー

有効な反論。読みやすさが心配です。通常、優れたモデルコードを理解するのは非常に簡単ですが、巨大なSQLクエリの樽をじっと見つめるだけでは、その意味がすぐにはわかりません。明らかに最初にすべきことはそれらのクエリを適切にコメントすることですが、それは良い自己文書化コードと同じではなく、これらのタイプのセクションはモデル全体に​​散らばっています。...私はそれを受け入れるが、分離株またはモデルに狂ったSQL文を整理するための良い方法がある場合、私は思っていた
jellyfishtree

0

モデルレイヤーを3つのサブレイヤー(「エンティティ」、「リポジトリ」、および「サービス」)に分けることをお勧めします。これにより、懸念事項を分離し、ビジネスロジックから1か所にSQLを収集できます。

このシナリオでは、複雑なSQLを含むすべてのデータ取得コードがリポジトリに配置されます。したがって、リポジトリの目標は、のような自明のメソッドの背後に複雑なSQLステートメントを隠すことgetUsersWithActiveSubscription()です。

エンティティは、実際のDBテーブルフィールド名をゲッターとセッターで抽象化し、DBフィールドタイプとアプリケーション/プログラミング言語で使用可能なタイプ間のデータ変換を提供します。ORMがサポートしている場合-エンティティは関連付けを処理できます。

サービス層は、ビジネスロジックの場所です。サービスは、リポジトリを使用してエンティティを取得し、それらに基づいて動作し、それらを保存します。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.