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


19

私は私が移動する方が良いだろう(もしあれば)どのような状況では、コードとEntity Frameworkののメイク使用されているすべての私のビジネス・ロジックを、持っている場合は、いくつかのストアドプロシージャにビジネスロジックを、代わりのコードでそれをすべて保ちますか?

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

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


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

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

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


4
どちらの状況も、ストアドプロシージャを作成する完全に正当な理由です。なぜ合法であるのかと尋ねていますか?
ロバートハーベイ

@RobertHarvey彼らが正当であることを確認し、例外を作成してストアドプロシージャをコードで保持するのではなく、他のシナリオや理由を探しています。
エイミーバレット

例外を作成し、使用可能な他の手法よりも問題を解決できると判断したら、ストアドプロシージャを作成します。
ロバートハーヴェイ

回答:


10

すでにいくつかの完全に良いシナリオがあります。

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

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

これら以外にももっとたくさんあるはずです。特定の状況で前進する最適なパスを決定する方法は、常識を使用し、主要な目標に焦点を当てることです。これは、高品質で保守が容易なコードを記述することです。それぞれの場合にこの結果を与えるツールを選択してください。


ジョエルのおかげで、あなたは私が考えていなかった他のいくつかのシナリオに言及しました。
エイミーバレット

いい答え。ただし、データベースに接続し、複雑なクエリまたはストアドプロシージャを実行しているユーザーが多い場合は、データベースサーバーに多くの負荷をかけることになりませんか。
リパルバロット

1
@RipalBarotワークロードでより多くの処理が行われる(ユーザーが増え、クエリが複雑になる)ほど、データベースサーバーの要求が増えることは間違いありません。ただし、留意すべきことの1つは、Entity FrameworkのようなORMではなくストアドプロシージャを使用すると、ストアドプロシージャがクエリプランをプリコンパイルできるため、ワークロードを(比較的)減らすことが多いということです。クエリがORMから送信される場合、DBMSは多くの場合、クエリの処理方法の決定から開始する必要があります。同等のストアドプロシージャを呼び出すと、データベースはそれを効率的に実行する方法をすでに知っています。
ジョエルブラウン

2

おそらく、質問を変えて、ストアドプロシージャだけが実行できるユースケースを見つけて、何を達成したいのかが理にかなっています。おそらく、ストアドプロシージャが際立っている実際の使用例があります。

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

EFに関する私の知識は限られていますが、私が見る限り、EFは(ちょうど)他のORMです。そして幸いにも使用することのできる生のSQLを

私があなたの2つの主要な点を取り上げると:

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

LINQ / EFは、レポートを作成するときに不足していました。お気づきSQLのとおり、ORMを使用するよりもはるかに高速でした。しかし、ストアドプロシージャに賛成して、またはすべてにORMを使用することに反対するだけで、これを語りますか?

あなたの問題はSQLで明らかに解決できます。そのクエリがコードベースに保存され、バージョン管理されている場合、例によると、少なくとも違いはありません

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

ここでも同じです:単純な接続文字列UPDATEで問題が解決しました。この問題を解決することができさえしてORM単に他のDBの前にWebサービスを使用し、同じcompartementalization / 分離が達成されます。

ここには何もありません。

他の人が作ったいくつかのポイントを見て:

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

しかし、それSQLはできます。ここには魔法はありません。

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

繰り返しますが、必要に応じてEFを使用します。

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

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

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

再び:「EFの境界」。

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

はい。多分行きます。

これまでのところ、ストアドプロシージャを支持する点は半分だけでした。


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

1)クエリを保存すると、複雑さをカプセル化するストアドプロシージャを簡単に呼び出すことができます。クエリプランナーはクエリを知っているため、最適化が「簡単」になります。ただし、現在の洗練されたクエリプランナー_minimalを使用すると節約できます。

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

2)それにもかかわらず、複雑なクエリをDBに保存することについて議論されました。考慮すべきことが2つあります。

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

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

tl; dr

ストアドプロシージャに直接反対するものはありません。したがって、ストアドプロシージャを使用しても大丈夫です。

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

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

適切な答えは次のとおりです。しかし、他のオプションがあります。


0

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

エンティティフレームワークは適切なジョブを実行し、パフォーマンスはストアドプロシージャの使用に近いか同等になります。エンティティフレームワークを選択したのは、SQLに関心がなく、フレームワークにSQLを生成させるためです。

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

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

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


100%が最後の段落に同意します
ユアン

0

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

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

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

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

一部のアドホックリクエストは、アプリのすべての機能を取得できるようになるまで、プロシージャを記述する方が簡単です。嫌いです。押し戻しますが、ショーは続けなければなりません。


0

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

一般的に言えば、SPを使用したいと思うのであれば、それはデータモデルがニーズにあまり適していないことを示唆する記号(コード臭)です。

編集:開発者がビジネス/データアクセスロジックについて尋ねると、ビジネスロジックはデータの動作と相互作用について、データアクセスロジックはデータの保存と取得についてです。

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

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

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


2
ビジネスロジックデータアクセスロジックをどのように定義しますか?
エイミーバレット


@RobertHarveyリンクをありがとう。データアクセス層はデータアクセスロジックと同じですか?データアクセスレイヤーに関係する実際のロジックはそれほど多くないようです。単純なCRUD操作だけです。
エイミーバレット

@AmyBarrett:さて、データアクセスレイヤーでカスタムメソッドを記述することがあるため、必ずしもCRUDとは限りません。
ロバートハーベイ

@RobertHarveyしかし、これらのカスタムメソッドはビジネスロジック層に属しませんか?
エイミーバレット

-4

ここには3つの問題があると思います。

  1. SQLのビジネスロジックは悪いです。個別に高速に実行されても、スケーリングしません。

  2. 従来、SPROCはすべてのデータアクセスに抽象化レイヤーとして常に使用する必要があります。DBAが消費アプリケーションに影響を与えることなく、パフォーマンスまたはその他のデータレイヤーの変更を導入できるようにします。

  3. EFはsprocsではうまく動作しません。Linqの動的クエリ生成から切り替えると、多くの「良い」機能と生産性の向上が失われます。

だから私の全体的なアドバイスは

  • すべてのSQLクエリにSPROCを使用します。

  • それらにビジネスロジックやループを入れないでください。

  • EFを使用しないでください。


すべてのSQLはdbサーバーで実行されるため、追加のコンピューティングボックスではなく、追加のdbでのみスケーリングできます。
ユアン

1
そうですか。ただし、ポイント1は純粋に2つのパフォーマンスの問題のトレードオフに関するものです。しかし、SQLソリューションがパフォーマンスの面で明確な勝利を収める場合があるため、これに基づいてカテゴリ別に「悪い」と見なされる方法はわかりません。

1
計算を行うWebサービスがあるとします。コードまたはSQLで実行できます。sqlは、単一の計算の直接テストで高速であると言います。しかし、サービスはその非常に安いと第二を追加しやすいCPUを限界に達し、第3、第4 ...ボックスのWebサービスが、第2レプリケートされたデータベースを追加するのは難しいと高価に実行されている場合
ユアン・

1
これは、スケーラビリティのためにSQL 不適切な設計になる可能性がある特定のシナリオの例です。しかし、それでも明らかではありません。予想されるユーザー数、外部と比較したデータベースでの計算実行の相対的なコストなどに依存します。もちろん、あなたはいくつかのケースで正しいです、私はそれが普遍的なルールだとは思わない。

3
これは全体的に悪いアドバイスです。ストアドプロシージャを手作業でコーディングするよりも利点があり、同様に機能するデータアクセスのオプションがたくさんあります。EFから直接sprocを実行できます。実際、EFからSQLクエリを直接実行できます。一部のビジネスロジックは、データベースサーバー上でより適切に実行されるため、そこで禁止されていると断言することはできません。オブジェクトリレーショナルマッパーは80%のツールです。データアクセスプロセスを完全に置き換えることを意図したものではありません。ストアドプロシージャは、ORMがうまく機能しない20%という用途に使用します。
ロバートハーヴェイ
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.