web-dev-qa-db-ja.com

ストアドプロシージャはいつ使用する必要がありますか?

コードにすべてのビジネスロジックがあり、Entity Frameworkを利用している場合、どのような状況で(ある場合)ビジネスロジックをsomeに移動した方がよいでしょう。すべてをコードで保持するのではなく、ストアドプロシージャ

明確にするために、私は現在のセットアップ(コード内のビジネスロジック)と組み合わせてではなく、という意味です。ストアドプロシージャにすべてのビジネスロジックを含めることの長所と短所を求める同様の質問をいくつか見ましたが、エッジケースロジックでのストアドプロシージャの使用を控え、残りのビジネスロジックを維持することについてはあまり知りませんでした。コードで。

違いがある場合は、MSSQLとEntity Frameworkを使用しています。


これらは、以前にストアドプロシージャを使用したことがある状況です。

  • 実行に数分かかっていた複雑なレポート(これはWebアプリのページでした)。 LINQが提供するよりもはるかに効率的な(実行に数秒しかかからない)SQLを記述できることがわかりました。
  • Webアプリケーションは、アプリケーションに関係のない他の多くの機密情報を含む別のデータベースのいくつかのテーブルを読み書きする必要がありました。すべてにアクセスできるようにするのではなく、必要なことだけを実行し、限られた情報しか返さないストアドプロシージャを使用しました。 Webアプリケーションは、このストアドプロシージャへのアクセスのみが許可され、テーブルなどへのアクセスは許可されません。

この質問をする前に私が見た他の投稿:

19
Amy Barrett

あなたはすでにいくつかの完全に良いシナリオを持っています。

他にも多くの理由があります。 EFは、CRUDと非常に簡単なレポートが得意です。ただし、EFが完全なツールではない場合もあります。ストアドプロシージャをEntity Frameworkと組み合わせて使用​​することを検討するその他の理由(シナリオ)には、次のようなものがあります。

  • EFの機能を使用して簡単にトランザクションにラップできない複雑な作業単位があり、おそらく多くのテーブルが含まれています。
  • 宣言的な参照整合性(外部キー制約)を利用できないため、データベースはEFでうまく機能しません。これは通常、自分にとっては不適切なシナリオですが、ETLプロセスに使用されるデータベースなど、適切なシナリオが時々あります。
  • リンクサーバーとサーバーの境界を越えるデータを操作する必要があります。
  • 適切なパフォーマンスを確保するために「ベアメタル」SQLが必要な非常に複雑なデータ取得シナリオがあります。たとえば、特定の状況でうまく機能するためにクエリヒントを必要とする複雑な結合があるとします。
  • アプリケーションにはテーブルに対する完全なCRUD権限はありませんが、サーバーが信頼するセキュリティコンテキスト(たとえば、ユーザーIDではなくアプリケーションID)でアプリケーションを実行することを許可できます。これは、DBAがストアドプロシージャへのテーブルアクセスを制限している状況でのみ発生する可能性があります。

これ以外にももっとたくさんあると思います。特定の状況での最適なパスを決定する方法は、常識を使用して、高品質でメンテナンスが容易なコードを記述することを第一の目標とすることです。いずれの場合も、この結果が得られるツールを選択してください。

11
Joel Brown

おそらく、質問を裏返して、onlyストアドプロシージャが実行できるユースケースを見つけ、達成したいことは、おそらく理にかなっています。おそらく、ストアード・プロシージャーが際立つユースケースがあるでしょう。

違いがある場合は、MSSQLとEntity Frameworkを使用しています。

私のEFに関する知識は限られていますが、私の知る限りでは、EFは(just)他のORMと同じです。 幸いにもraw SQLを使用できます。

私があなたの2つの主要なポイントを取るとしたら:

実行に数分かかっていた複雑なレポート(これはWebアプリのページでした)。 LINQが提供するよりもはるかに効率的な(実行に数秒しかかからない)SQLを記述できることがわかりました。

[〜#〜] linq [〜#〜]/[〜#〜] ef [〜#〜]レポート作成時に不足していました。お気づきのとおり、ORMを使用するよりもSQL高速でした。しかし、ストアドプロシージャを支持してこれを話すか、または[〜#〜] orm [〜#〜]をすべてに対して使用することに対してonly

あなたの問題は明らかに[〜#〜] sql [〜#〜]で解決できます。そのクエリが格納され、コードベースでバージョン管理されている場合-例によれば-少なくとも違いなしになります。

Webアプリケーションは、アプリケーションに関係のない他の多くの機密情報を含む別のデータベースのいくつかのテーブルを読み書きする必要がありました。すべてにアクセスできるようにするのではなく、必要なことだけを実行し、限られた情報しか返さないストアドプロシージャを使用しました。 Webアプリケーションは、このストアドプロシージャへのアクセスのみが許可され、テーブルなどへのアクセスは許可されません。

同じこと:単純な接続文字列[〜#〜] update [〜#〜]で問題が解決しました。この問題は解決できます偶数[〜#〜] orm [〜#〜]simply他の前でWebサービスを使用DBと同じcompartementalization/isolationが達成されます。

ここには何も表示されません。

他の人が作ったいくつかの点を見る:

EFの機能を使用して簡単にトランザクションにラップできない複雑な作業単位があり、おそらく多くのテーブルが含まれています。

しかし、SQLはそれを行うことができます。いいえmagicここには関与していません。

データベースがEFでうまく機能しない

繰り返しますが、必要に応じて[〜#〜] ef [〜#〜]を使用します。

リンクサーバーとサーバーの境界を越えるデータを操作する必要がある

ストアドプロシージャがどのように役立つかわかりません。したがって、私はできませんseeストアドプロシージャの利点。しかし、おそらく誰かがそれについていくつかの光を投げかけています。

適切なパフォーマンスを確保するために「ベアメタル」SQLが必要な非常に複雑なデータ取得シナリオがある

繰り返します:「[〜#〜] ef [〜#〜] "の境界。

アプリケーションにはテーブルに対する完全なCRUD権限がありませんが、サーバーが信頼するセキュリティコンテキストでアプリケーションを実行することを許可できます

はい。私はたぶんで行きます。

これまでのところ、ストアドプロシージャを支持してhalfポイントが作成されました。


おそらく、ストアード・プロシージャーを支持するパフォーマンスの考慮事項があります。

1)クエリの保存には、複雑さをカプセル化するストアドプロシージャへのsimple呼び出しという利点があります。クエリプランナーはクエリを知っているので、最適化は「簡単」です。しかし、節約は現在の洗練されたクエリプランナー_minimalで行われます。

その上、ad hocクエリを使用するとわずかなコストがかかる場合でも、データが適切に構造化されており、慎重にインデックスが作成されている場合、databaseにすぎませんアプリケーションのボトルネック。したがって、小さなデルタがあったとしても、他の要因を考慮すると無視できます。

2)それにもかかわらず、それはcomplexクエリをDBに保存するために議論されました。考慮すべき点が2つあります。

a)複雑なクエリはDBインフラストラクチャを大量に使用するため、他のすべてのクエリの処理時間が長くなります。 並列では、多くのコストがかかるクエリを実行できません。これはprocontraストアドプロシージャも話しませんが、-complexクエリに対しては無効です。

b)とにかくクエリに時間がかかる場合は、なぜストアドプロシージャの速度が遅いのかわからない。

tl; dr

againstストアドプロシージャが直接話すことはありません。したがって、ストアドプロシージャの使用は問題ありません。

しかし、その一方で、適切なユースケースが話す不明確なプロを想像することはできませんでした。

ストアドプロシージャはいつ使用する必要がありますか?

正解は次のとおりです:好きなときに。しかし、他のオプションがあります。

2
Thomas Junk

ストアドプロシージャにbusinessロジックを配置しないことを強くお勧めします。ただし、データアクセスロジックをそこに配置することが望ましい場合があります(2つの優れた例をリストしました)。

一般的に言えば、SPを使いたくなったら、それはデータモデルがそのニーズにあまり適していないことを示す兆候(コードのにおい)です。

編集:開発者がビジネス/データアクセスロジックについて尋ねるとき、私はビジネスロジックはデータの動作と相互作用についてであるのに対し、データアクセスロジックはデータが格納および取得される方法についてであると言います。

例:ドメインモデルに、「Person」から派生した「Student」と「Teacher」というエンティティがあるとします。 (これが好ましいと言っているのではなく、単なる例です)。これは、1つ、2つ、または3つのテーブルとしてリレーショナルデータベースに保存できます。選択は、それらが共有するプロパティの数、および読み取り/書き込みのパフォーマンス要件によって異なります。

ビジネスロジックでは、これらのエンティティがどのように格納されるかは重要ではありません。 (またはそれらがRDBに存在するかどうか)。データアクセスロジックは、それらが物理的にどのように格納されるかについてのすべてです。

したがって、元の質問について:ストアドプロシージャによってデータの保存と取得がより効率的に(またはより堅牢に)なる場合は、ケースがあります。ストアドプロシージャが、データの格納方法に関係なく有効なルールを課すためだけのものである場合は、それを避けてください。これにより、コードがデータベースとより密接に結合されます。

0
Guran

特定のケースでは、エンティティフレームワークを使用しているため、エンティティフレームワークが要件または懸念事項を満たさない場合は、ストアドプロシージャの使用を検討する必要があります。

エンティティフレームワークは適切な仕事をしており、パフォーマンスはストアドプロシージャの使用とほぼ同じかそれと同等です。 SQLに関心がなく、フレームワークにSQLを生成させるため、エンティティフレームワークを選択しました。

しかし、エンティティフレームワークが不十分で、ニーズを満たせないEdgeケースがある場合があります。この場合、ストアドプロシージャまたはパラメーター化されたクエリを使用してSQLを手動で記述し、エンティティフレームワークを使用して、そのストアドプロシージャ/ SQLステートメントを直接呼び出します。

そのため、使用されているフレームワークが要件を満たさない限り、ストアドプロシージャには何も移動しません。

起こり得る最悪のことは、エンティティフレームワークを使用することを選択し、すべてのストアドプロシージャを書き込むことです。これで、付加価値のない追加のレイヤーができました。

0
Jon Raynor

技術的なニーズがあることは、最もありそうな選択ではありません。プログラマーは自分たちのツールを好み、通常は自分たちの問題を解決することにもっと順応しています。ロジックをsprocに入れることは例外です。技術的な負債と、例外を伴う作業に時間を費やさなければならない将来の開発者は考慮されるべきです。特定のRDBMSのパフォーマンスが向上する可能性があります。これは、sprocまたはインデックス付きビューのような別のdbオブジェクトで実装する方が簡単です。

データベースからのデータが必要で、アプリケーションコードから取得できない場合があります。多くの大企業/企業の状況では、ビジネスニーズがIT部門の把握を超える可能性があります。企業は売買され、彼らのアプリケーションは行き来します。規制当局や銀行は、非常にスケーラブルで美しくコード化されたアプリを構築できなくても構いません。彼らはビジネスにとって人生を困難にする可能性があるので、あなたはそれを成し遂げる必要があります。

サードパーティのアプリケーションやレポート作成ツールではコードを実行できない状況に遭遇しました。オープンソースコード、API、Webインターフェイス、サービスはありません。彼らが持っている唯一のものは、データベースオブジェクト(テーブル、ビュー、sprocs、ユーザー定義関数など)でのみ機能する独自の特別なレポート作成ツールです。ロジックをどこにでも配置できます。

ストアドプロシージャの作成に非常に優れたDBAがいる場合は、状況によってはその才能を活用できます。データを大幅に変更するため、アプリからバックアップをトリガーする必要がある場合があるので、dbaが使用するものを使用してみませんか?

一部のアドホックリクエストは、アプリのすべての機能を利用できるようになるまで、プロシージャを記述する方が簡単です。嫌いです。我々は押し戻しますが、ショーは続く必要があります。

0
JeffO