-5

重複の可能性:
SQL をストアド プロシージャとコードに保持することの長所と短所は何ですか

ストアド プロシージャを使用することと、データベースからデータを取得する他の形式を使用することの利点と欠点に興味があります。速度、精度、およびセキュリティを確保するための推奨される方法は何ですか (SQL インジェクションは必要ありません!)。

(この質問を別のスタック交換サイトに投稿する必要がありますか?)

4

3 に答える 3

0

この問題に関する Stackoverflow に関する質問がいくつかあります。ここで「正しい」答えが得られるとは本当に思いません。どちらもうまくいく可能性があり、どちらもひどくうまくいく可能性があります。Java を使用している場合、一般的なパターンは Hibernate/JPA のような ORM フレームワークを使用することだと思います。フレームワークを正しく使用している限り、これは SQL インジェクション攻撃から完全に安全です。.Net 開発者との私の経験では、ストアド プロシージャに基づく永続性を使用する可能性が高くなりますが、それは以前よりもオープンになっているようです。NHibernate と他の MS テクノロジの両方が人気を集めているようです。

私の個人的な見解では、通常、ORM を使用すると、典型的な CRUD 型システムで使用する SQL の多くを自動的に生成できるため、多くの冗長なコーディングからいくらかの時間を節約できます。これを実現するには、多少のパフォーマンスとある程度の柔軟性を犠牲にする可能性があります。システムのボリュームが少量から中程度 (1 日に数万件のリクエスト) の場合は、ORM で問題ありません。1 日に数百万のリクエストを処理し始める場合は、単純な SQL やストアド プロシージャなど、もう少しベア メタルが必要になる場合があります。ORM はDB に直接アクセスすることを妨げないことに注意してください。これは通常、使用するものではありません。

最後に、ORM の永続性により、アプリケーションのテストがはるかに容易になると思います。永続化の多くにストアド プロシージャを使用する場合、ストアド プロシージャに一連のビジネス ロジックを追加することになります。それらをテストするには、実際にデータを永続化し、DB とやり取りする必要があります。これにより、テストが遅くなり、脆弱になります。ORM フレームワークを使用すると、このテストのほとんどを回避するか、本当に永続性をテストしたい場合にインメモリ DB を使用できます。

見る:

于 2012-07-09T19:06:27.067 に答える
0

すべてのデータベースの質問に対する回答によると、「それは依存します」。ただし、ストアド プロシージャは確実に速度の点で役立ちます (ただし、適切にパラメーター化された SQL は、プラン キャッシュの恩恵も受けます)。精度も同じです。不適切なクエリは、ストアド プロシージャ内にあるかどうかに関係なく、正しくありません。また、セキュリティの観点から、ユーザーのアクセスを制限する便利な方法を提供できます。基になるテーブルへの直接アクセスを許可する必要がないため、必要なストアド プロシージャの実行をユーザーに許可するだけです。ただし、このトピックには多くの質問があるため、少し検索してさらに調べることをお勧めします。

于 2012-07-09T19:01:46.300 に答える
0

これは Programmers SE の方が優れているかもしれませんが、ここで回答します。

CRUD ストアド プロシージャは、SQL DBMS でのデータの永続化と検索のベスト プラクティスであり、現在もそうです。そのようなすべての DBMS にはストアド プロシージャがあるため、コーディング言語や DBMS に関係なく、このソリューションを使用できることが実質的に保証されます。ソリューションを使用するコードは、適切なストアド プロシージャを持つ任意の DB を指すことができます。最小限のコード変更で動作します (異なる DBMS で SP を呼び出す場合、いくつかの構文変更が必要です。多くの場合、これらは、特定の DBMS で SP にアクセスするための言語のライブラリ サポートに統合されます)。おそらく最大の利点は、テーブル データへの集中アクセスです。Fort Knox のようにテーブル自体をロックダウンし、必要に応じて SP のアクセス権をより制限されたユーザー アカウントに分配できます。

ただし、いくつかの欠点があります。まず、ツールはデータベース IDE 内に実際には存在しないため、SP は TDD が困難です。SP を実行する他のコードでテストを作成する必要があります (したがって、テストでは、期待されるテスト データを使用して DB をセットアップする必要があります)。技術的な観点からは、このようなテストは「単体テスト」ではありません。また、「単体テスト」になることはできません。これは、小さくて狭い機能領域の小さくて狭いテストであり、副作用(ファイル システムへの読み取り/書き込みなど)はありません。 )。また、SP は、機能に必要な変更を加えるときに変更する必要があるもう 1 つのレイヤーです。クエリ結果に新しいフィールドを追加するには、テーブル、検索ソース コード、および SP を変更する必要があります。. 特定のタイプのレコードを検索する新しい方法を追加するには、ステートメントを作成してテストし、SP にカプセル化し、DAO で対応するメソッドを作成する必要があります。

利用可能な新しいベスト プラクティスである IMO は、オブジェクト リレーショナル マッパーまたは ORM と呼ばれるライブラリです。ORM は実際のデータ レイヤーを抽象化するため、求めているのはコード オブジェクト自体になり、テーブル データではなく、それらのオブジェクトのプロパティに基づいてクエリを実行します。これらのクエリは、ほとんどの場合、コードで構成可能であり、オブジェクト モデルとデータ モデルの間で定義した 1 つまたは複数の "マッピング" に基づいて、DBMS の SQL に変換されます (タイプ A のオブジェクトは、テーブル B のレコードとして保持されます。ここで、このプロパティ C はフィールド D に書き込まれます)。

利点は、これらのコード オブジェクトの形式でデータを実際に検索するコード内での柔軟性が高いことです。通常、クエリの条件はコード内でカスタマイズできます。別の WHERE 句を持つ新しいクエリが必要な場合は、クエリを記述するだけで、ORM がそれを新しい SQL ステートメントに変換します。ORM は SQL が実際に使用される唯一の場所であるため (また、ほとんどの ORM はシステム ストアド プロシージャを使用して、可能な場合はパラメーター化されたクエリ文字列を実行します)、インジェクション攻撃は事実上不可能です。最後に、言語と ORM によっては、クエリをコンパイラでチェックできます。.NET では、Linq と呼ばれるライブラリが利用可能で、SQL っぽいキーワード構文を提供します。これは、メソッド呼び出しに変換され、それらのメソッド呼び出しをデータ ストアに変換できる「クエリ プロバイダー」に渡されます。ネイティブのクエリ言語。これにより、クエリをコード内でテストすることもできます。実際の DBMS を表すメモリ内のオブジェクトのコレクションが与えられた場合、使用したクエリが目的の結果を生成することを確認できます。

ORM の欠点は、通常、ORM ライブラリが言語固有であることです。Hibernate は Java、.NET の NHibernate (および L2E と L2SQL)、および PHP の Pork のようないくつかの同様のライブラリで利用できますが、古い言語やより難解な言語でコーディングしている場合、利用できる種類のものは何もありません。もう 1 つの問題は、セキュリティが少し複雑になることです。ほとんどの ORM は、テーブルをクエリおよび更新するために、テーブルに直接アクセスする必要があります。一部の人は、取得用のビューと更新用の SP を指すことを許容します (ビュー/SP とテーブルのセキュリティを分離し、取得可能なフィールドを制限する機能を許可します)。マッピングを定義する必要はありますが、データ層にもコードがあります。これを克服する最も簡単な方法は、セキュリティを別の場所に実装することです。ORM を使用してデータを提供し、特定の限定された「正面玄関」を持つ Web サービスを使用してアプリケーションにデータを取得させる。また、多くの ORM は、特定の方法で使用するとパフォーマンスの問題が発生します。ほとんどはデータを「遅延ロード」するように設計されており、データが実際に必要になった瞬間に取得されます。これにより、要求したすべてのレコードが必要ない場合の先行パフォーマンスが向上します。ただし、要求したすべてのレコードが必要な場合は、余分なラウンド トリップが作成されます。この予想されるユースケースの動作を回避するには、特定の方法でクエリを構成する必要があります。データが実際に必要になったときに取得され、それ以前ではなく取得されるため、要求したすべてのレコードが必要ない場合でも、事前のパフォーマンスが向上します。ただし、要求したすべてのレコードが必要な場合は、余分なラウンド トリップが作成されます。この予想されるユースケースの動作を回避するには、特定の方法でクエリを構成する必要があります。データが実際に必要になったときに取得され、それ以前ではなく取得されるため、要求したすべてのレコードが必要ない場合でも、事前のパフォーマンスが向上します。ただし、要求したすべてのレコードが必要な場合は、余分なラウンド トリップが作成されます。この予想されるユースケースの動作を回避するには、特定の方法でクエリを構成する必要があります。

どちらが良いですか?あなたが決めなければなりません。ORM を使用すると、SP よりもセットアップして正しく動作させるのがはるかに簡単であり、スキーマとクエリを変更する (および範囲を制限する) のがはるかに簡単であることがわかります。優先順位が最初に機能するようにすることであり、次にそれを適切に実行すること、および/または侵入に対して安全にすることが優先される現代の開発会社では、それは大きなプラスです. セキュリティが問題であると考えるほとんどの場合、実際にはそうではありません。また、セキュリティが実際に問題である場合、DB レイヤーにソリューションを配置することは、通常、間違った場所です。DBMS は防御の最後のラインであるためです。侵入に対して; 望ましくないことが起こるのを止めるために DBMS 自体を頼りにする必要がある場合、その上にあるソフトウェアとファームウェアの多くの層でそうすることができませんでした (またはそれが起こるように促すことさえありません)。

于 2012-07-09T19:09:44.230 に答える