2009-07-23 8 views
30

ロジックをアプリケーションに直接書き込むのではなく、いつストアドプロシージャを使用する必要がありますか?私はストアドプロシージャのメリットを享受したいと思いますが、アプリケーションロジックをデータベースとアプリケーションに分散させたくありません。ストアドプロシージャはいつ使用しますか?

これに関連して考えられるルールはありますか?

+0

phpタグを削除することをお勧めします。これは、他のプログラミング言語でも簡単に使用できます。 – Iain

答えて

29

うわー...私はここの流れに対して直接泳ぎ、「ほとんどいつも」と言います。理由の洗濯物のリストがあります - いくつか/多くの私は他人が議論すると確信しています。しかし、私は、データアクセス層としてストアドプロシージャを使用する場合と使用しない場合の両方でアプリケーションを開発しましたが、よく書かれたストアドプロシージャを使用するとアプリケーションを書くのがずっと簡単になりました。次に、パフォーマンスとセキュリティのメリットについて十分に文書化されています。

+6

*よく*文書化されたパフォーマンスとセキュリティ上の利点。ちょうどそれを言いたかった。私たちはTSQLをアプリケーションに使用していません。 SQLはストアドプロシージャ内にあり、プロシージャはコードから呼び出されます。選択されたステートメントほど多くのコードに触れることはありません。 SPを実行するかどうかは、事前にコンパイルされたコードと解釈されたコードの違いです。どれを好むのですか?あなたの質問に対する答えは「常に」です。 – Jeremy

+4

「十分に文書化された」パフォーマンス項目は、実際に使用しているデータベースエンジンによっては問題になりません。ただし、セキュリティ上の理由から、ストアドプロシージャを使用する必要があります。 procsを使用すると、ダイレクト・テーブル・アクセスを拒否することができ、破壊的なSQLインジェクションのほとんどのフォームに対して自分自身を完全に保護することができます。それ以外の場合は、コードに依存して停止します。すべてのプログラマーが平等に作成されているわけではありません。 – NotMe

+2

@Chris Lively:パラメータ化されたクエリはSQLインジェクションに対して最も安全です。参照してくださいhttp://palisade.plynt.com/issues/2006Jun/injection-stored-procedures/ –

4

私はストアドプロシージャを避ける傾向があります。デバッグツールはより原始的な傾向があります。エラー報告は難しくなる可能性があります(サーバーのログファイルと比較して)少なくとも、実際の利益が得られない別の言語が追加されたようです。

特に、サーバー上で大量のデータを処理する場合や、コードで実行できないデータベーストリガーを処理する場合に役立つ場合があります。

しかし、私はコードですべてを行い、コードを実行するのではなく、データの大きなダンプとして扱う傾向があります。

Who Needs Stored Procedures, Anyways?を考えてみましょう:現代のデータベースと現実世界 使用シナリオについては

を、私は、ストアド・プロシージャ アーキテクチャが深刻 欠点と少し実用的な 利点を持っていると信じています。 ストアドプロシージャ データベースアセンブリ言語: としてください。最も重要なのは、 重大な状況のみです。

Why I do not use Stored Procedures

絶対最悪のことを行うことができます、 それは、 Microsoft開発の世界でhorrifyingly一般的です split related functionality between sproc's and middle tier codeにあります。 Grrrrrrrr。あなたはコード を脆くして、 の理解の知的オーバーヘッドを 増加させます。

+3

悪い例では、メソッドが適切に使用されている場合の利点を排除しません。 – txwikinger

+0

ある人の「悪い例」は、別の男の「何かが悪い理由の良い例」です。 – cletus

+1

@cletusは意味をなさない。例は常に限定されており、一般化を証明しません。 – txwikinger

4

基本的に、データベースから出る必要のないデータを含む操作を実行する必要がある場合。たとえば、1つの表を別の表のデータで更新する場合は、データを1つの単一ショットですべてデータベースから実行できる場合は、データを取得して戻すことはほとんど意味がありません。

ストアドプロシージャを使用することが許容される別の状況は、アプリケーションを他のデータベースベンダーに展開しないことを100%確信している場合です。あなたがOracleのお店であり、同じデータベースに対話しているアプリケーションがたくさんある場合、ストアドプロシージャを使用して、すべてが一貫した方法でdbと対話できるようにすることは理にかなっています。

4

私にとって複雑なデータベースクエリは、ストアドプロシージャとして終わる傾向があります。考慮すべきもう一つの考え方は、データベースがアプリケーションとは完全に別個のものであることです。あなたはOracle DBを実行し、本質的にあなたの組織の他のアプリケーション開発者がコールするためのAPIを構築していると言います。あなたはそれらから複雑なものを隠し、その場所にストアされたprocを提供することができます。

非常に単純な例:

registerUser(username, password) 

は、いくつかの異なるクエリを実行するに終わるかもしれない(それが存在する場合など、好みのテーブルのエントリを作成し、確認してください)、あなたはそれらをカプセル化したい場合があります。

もちろん、異なる人が異なる視点(DBAとプログラマ)を持つことになります。

+0

+1非常に良い点は、限られたデスクトップアプリケーションをコーディングするときでも、複雑なデータベースのメンテナンス処理をラップアップしてアプリケーションコードから隠しておくのが良いので、同じことをやります。 – Cruachan

2

また、カプセル化の問題とDRYの哲学に非常に役立ちます。たとえば、私はコード内のいくつかのクエリに必要なテーブル内の計算のためにストアドファンクションを使用します。このようにして、より良いパフォーマンスと、計算が常に同じように行われるようにします。

アーキテクチャのビジネスロジックレイヤーにあるより高い機能性やロジックには使用しませんが、モデルレイヤーに重点を置いています。ここでは、機能がデータベース設計に重点を置いており、データベースの変更の柔軟性APIを他の層に壊すことなく設計できます。

2

私たちは、すべての報告ニーズに合わせてストアドプロシージャを使用します。彼らは通常、より速く、何らかの計算やそれに類することをするのではなく、レポートをただちに吐き出すことができるように、データを迅速に取り出すことができます。

複雑なクエリや複雑なクエリにストアドプロシージャを使用することもあります。これは、そうでなければコードベース内にある場合は読みにくいでしょう。

4

私は1 3のシナリオに保存されprocsのを使用:

スピード 速度が最も重要である場合は、ストアドプロシージャは、優れた方法を提供

複雑 私はいくつかの更新をしていた場合テーブルとコードロジックは、私はストアドプロシージャを更新し、再コンパイルを避けることができる道を変更する可能性があります。ストアドプロシージャは、1回のストロークで多数のデータを更新するための優れたブラックボックスメソッドです。

トランザクション 私は挿入を処理しているときに、複数のテーブルにまたがる削除または更新を行います。私はトランザクションですべてを包みます。エラーが発生した場合は、トランザクションをロールバックしてデータ破損を防ぐためにエラーをスローするのは非常に簡単です。

下の2はコードでは非常に可能です。ただし、ストアドプロシージャは、複雑なトランザクションレベルの操作が重要な場合には、ブラックボックスの処理方法を提供します。それ以外の場合は、コードレベルのデータベース操作を行います。

セキュリティは理由の1つだった。ただし、LINQやその他のORMを使用すると、コードレベルのDAL操作は以前よりもはるかに安全です。ストアドプロシージャは安全ですが、LINQのようなORMもそうです。依然としてデータベース側でそれらを維持しながら

0

ストアドプロシージャは、データベース側に一緒に行うべき操作を収集する方法です。

これには、

  • 異なるビジネスルールに対する複数のテーブルをチェックする1つの値集合ソース
  • から複数のテーブルを移入効率的に設定ベースのアプローチを用いて行うことができない
  • 実行操作

ストアドプロシージャは、維持するのが難しいということです。

したがって、ストアドプロシージャは、他のすべてのコードと同じように保守する必要があります。

は、私は私のブログにこの記事を持っている:これは、ご使用の環境に完全に依存し

15

。質問への答えは実際にはコーディングの問題ではなく、分析の問題でもビジネス上の決定ではありません。

データベースがアプリケーションを1つしかサポートしておらず、それと緊密に統合されている場合は、柔軟性の理由から、ロジックをアプリケーションプログラム内に配置する方がよいでしょう。このような状況では、一般的な機能を使用してデータベースを単純なデータリポジトリとして扱うことは、ベンダー、実装、導入などの柔軟性をほとんど失うことなく、「データベースはデータを集める」という多くの純粋主義的主張が実証されています本当。

一方、一般に複数のアクセスパスを持つことで識別できる企業データベースを処理している場合は、可能な限りセキュリティを徹底的に停止することをお勧めします。少なくとも、すべての適切な制約を有効にする必要があります。可能であれば、データへのアクセスは、ビューとプロシージャを介してのみ行う必要があります。泣き言プログラマは、資産のデータやアクションがビジネスを脅かす結果を持つことができる貴重かつ無効であり、企業のデータベースと

  1. ...として、これらのケースでは無視されなければなりません。あなたの主な関心事は、あなたのコーダーにとってどのように便利なアクセスではなく、ビジネスを守ることです。
  2. このようなデータベースは、複数のアプリケーションによって定義されています。アプリケーションAがアップグレードされ、アプリケーションBをアップグレードするリソースがない場合にデータベースを変更できるように、ストアドプロシージャが提供する抽象化を使用する必要があります。
  3. 同様に、ビジネスロジックをアプリケーションコードではなくSPにカプセル化しますそのようなロジックがアプリケーションコードに埋め込まれている場合よりも、より簡単かつ確実にビジネス全体にそのようなロジックを変更することができます。たとえば、1つのSPで複数のアプリケーションよりも計算を変更する必要がある場合は、税計算が変更された場合は作業が少なく、より堅牢です。ここでの経験則では、ビジネスルールは固有のデータに最も近いところに実装する必要があるため、専門アプリケーションを使用する場合はそのアプリケーションのロジックをそのアプリケーションに実装できますが、ロジックはより広範囲に適用できますSPにビジネスを実装する必要があります。 SPの使用またはいない上で宗教戦争に飛び込む

コーダーは、一般的に一つだけの環境で働いていた、または他ので、鋳鉄製の位置に自分の限られた経験を推定している - 確かに完全に防御し、正しいだろう彼らが来るが大きな絵を見逃している文脈の中で。いつものように、ビジネス/顧客/ユーザーのニーズを判断し、どのタイプのコーディング方法を好むかを決めるべきではありません。

0

私はこれに関して非常に悪い経験をしています。

私は彼らの代わりにストアドプロシージャに反対していませんが、ストアドプロシージャの無償使用は非常に高価になる可能性があります。

まず、ストアドプロシージャはデータベースサーバー上で実行されます。つまり、50台の安価なマシンにワークロードを分散するのではなく、50台のWebサーバーと1台のデータベースサーバーを備えたマルチサーバー環境の場合は、1台の高価なサーバーをロードします(通常、データベースサーバーは重量サーバーとして構築されるためです)。また、単一障害点を作成するリスクがあります。

第2に、ストアドプロシージャだけでアプリケーションを書くのは簡単ではありませんが、試してみると非常に手間がかかっていました。ストアドプロシージャはソースアーカイブにではなく、DBMSに確実に格納されるため、2つの異なるプログラミング言語で実装されており、ソースコードはすべて1つの場所に収まるわけではありません。誰かが管理/悩まされていると仮定すると、それらをデータベースサーバから取り出し、ソースアーカイブすることはまったくありません。

非常に乱雑なアプリケーションアーキテクチャとは別に、複数のスキルが必要なため、それを維持できる適格なチンパンジーのセットも制限しています。一方

場合は、ストアドプロシージャは、非常に便利です:あなたは、複数のシステム間でデータの整合性のいくつかの並べ替えを維持する必要が

  1. 。つまり、保存されたロジックは単一のアプリには属しませんが、参加しているすべてのアプリから一貫した動作が必要です。現代のアプリケーションでは、外部キーやトリガの形でこれに一定の量がほとんど不可避ですが、場合によっては主要な編集や検証も正当化されることがあります。

  2. パフォーマンスは、データベースサーバー自体ではなくクライアントとして実行することによってのみ達成できます。しかし、私が言ったように、そうすると、DBMSサーバーのシステムリソース全体を食い込んでいるのです。したがって、クライアントにオフロードできる違反操作が多ければ、それらを分離してDBMSサーバーにとって最も重要なものにすることができます。

+1

"50ウェブサーバー"をお持ちの場合は、少なくとも1つのDBAをお持ちであれば幸いです。誰がTSQLを知っている。どのストアドプロシージャが書かれているのですか。それについては何も面倒ではありません。何が面倒なのはストアプロシージャを使用していないことです。 – Jeremy

+1

ストアドプロシージャは、必要なデータベースサーバーの数とは関係ありません。単純な理由は、それがprocまたは組み込みSQLであれば問題ではなく、DBサーバーはまだコードを実行する必要があるということです。 – NotMe

+2

"ストアドプロシージャはDBMSに格納されており、ソースアーカイブには格納されていないため" Bad developers。常に、ソース・アーカイブにストアド・プロシージャーを保持します。また、ソースアーカイブからすべてのデータベースに流れ込むため、データベースから取り出してソースアーカイブに入れる必要はありません。 (開発時に開発されている場合は除きます) –

2

私は常にストアドプロシージャを使用する傾向があります。個人的には、すべてを維持しやすくしています。セキュリティとパフォーマンスに関する考慮事項があります。

きれいで、うまくレイアウトされ、文書化されたストアドプロシージャを作成してください。

9

私はこれをコメントで言いましたが、ここでもう一度言います。

セキュリティ、セキュリティ、セキュリティ

アプリケーションにSQLコードが埋め込まれている場合は、基になるテーブルを直接アクセスできるように公開する必要があります。これはかもしれません最初に大丈夫です。あなたがデータベースのすべてのvarcharフィールドをスクランブルするいくつかのSQLインジェクションでヒットするまで。

マジッククォートや埋め込みSQLを正しくエスケープする他の方法を使用してこの問題を回避すると言う人もいます。しかし、問題はdevが正しくエスケープしなかった1つのクエリです。または、コードをアップロードすることを忘れた開発者。または、攻撃者がコードをアップロードすることを許されたクラックされたWebサーバー。または、あなたはポイントを得る。すべてのあなたの拠点をカバーするのは難しいです。

は私のポイントは、すべての近代的なデータベースは、セキュリティが組み込まれています。あなたは、単に直接テーブルアクセス拒否(選択、挿入、更新、および削除)し、あなたのs'procsを通過するすべてのものを強制することができます。これにより、一般的な攻撃はもはや機能しなくなります。代わりに、攻撃者はあなたのシステムの詳細を学ぶために時間をかける必要があります。これは、費やされる時間の観点から彼らの「コスト」を増加させ、ワーム攻撃による駆動を止める。

私たちはすべてのものから自分自身を守ることはできないと知っていますが、時間をかけてアプリケーションを設計すれば、それを上回るコストがそれを上回るので、データ損失の可能性を大幅に減らすことになります。これは、利用可能なすべてのセキュリティツールを活用することを意味します。

s'procsを使用していないという考えを最後に

、あなたは別のRDBMSへのポートが必要になる場合がありますので:まず、ほとんどのアプリケーションは、データベース・サーバを変更しないでください。第二に、本当の可能性がある場合は、とにかくANSI sqlを使用してコードを作成する必要があります。あなたはあなたのprocsで行うことができます。第三に、何があってもsqlコードをすべて再評価しなければならず、そのコードが1つの場所にある場合はずっと簡単です。第4に、現代のデータベースはすべてs'procsをサポートしています。第5に、s'procを使用すると、実行しているデータベースのSQLをカスタマイズして、その特定のデータベースのSQL拡張機能を利用することができます。

+1

もう1つのメリットは、すでにリリースされているアプリケーションのs'procsでsqlコードを変更する方が、マイナーなクエリ変更のためにアプリケーション全体を再デプロイする方が簡単です。 – NotMe

0

"(n + 1)"スケーラビリティの問題を抱える状況には、特定のシナリオがあります。あらゆる種類の多次元/階層的状況がこのシナリオを含む可能性が高い。

別のシナリオには、テーブルを処理する際にプロトコルを使用するユースケースがあります(ヒント:トランザクションが関与する可能性のある定義済みのステップ)。これは参照のローカリティから利益を得ることができます。 OTOHでは、サーバーにステートメントのバッチを直接提供することができます。特に、XA環境で、連合データベースにアクセスする必要がある場合。

1

速度とセキュリティ上の考慮事項の上で、私は、保守や変更を容易にするために、できるだけ多くのストアドプロシージャを使用する傾向があります。ロジックをアプリケーションに配置し、後でSQLロジックにエラーがある、または何らかの方法で別の方法で動作する必要がある場合は、多くの場合、アプリケーション全体を再コンパイルして再デプロイする必要があります(特に、WPF 、Win-Formsなど)。ストアドプロシージャにロジックを保持する場合は、procを更新してアプリケーションに触れる必要はありません。

0

"一般的にsprocsを使うべきか"というのではなくビジネスロジックを話しているのであれば、大規模なセットベースの操作を実行しているときや、ロジックを実行するときにsprocsにビジネスロジックを置く必要があります。アプリからのdbへの多数の呼び出し。

0

これは視聴者によっても異なります。 DBMS間のインストールと移植の容易さは重要ですか?

プログラムをインストールしやすく、異なるデータベースシステムで実行しやすいようにする場合は、ストアドプロシージャから離れてコード内の移植性のないSQLを調べる必要があります。

+0

ええ、人々はいつも非標準SQLを避けるべき理由としてこれを挙げていますが、実際にはデータベースベンダーをスワップする理由はほとんどありません(私は30年後にITでそれを見たことはないと思います非常に些細なプロジェクトを除いて) – Cruachan

2

すべてのコードがストアドプロシージャ内にある場合、必要に応じてデータベースをリファクタリングする方がはるかに簡単です。ロジックへの変更は、プッシュするのがはるかに簡単です。また、パフォーマンスチューニングがはるかに容易で、遅かれ早かれ、ほとんどのデータベースアプリケーションでパフォーマンスチューニングが必要になります。

0

私はそれらをよくよく使うべきだということに同意します。

私が思うに、非常に魅力的で非常に有用なのは、いくつかのデータにすでに存在していて必要なレコードがいくつかのテーブルに分かれているはずの生の情報をたくさん取っている場合です外部キーIDで接続されている場合は、EXISTSがチェックして挿入していない場合は挿入し、そうでない場合はキーを返すことで、すべてをより統一的、簡潔かつ保守性の高いものにできます。

あなたがロジックや最高のアプリケーションサーバーで実行されたクエリOR間の数値演算の多くを行っている場合は、すべてのを維持する会社のために働いている場合、私はそれらを使用してに対してを示唆しているだけの場合がありますコード内のロジックのは、何が起こっているかの維持/理解のために重要です。 gitリポジトリに誰かが必要とするものがいっぱいで、簡単に理解できるものがあれば、それは非常に貴重なものになります。

関連する問題