web-dev-qa-db-ja.com

ストアドプロシージャは、世界最大のITソフトウェアコンサルティング会社の悪い習慣ですか?

私は世界のトップ3のITコンサルティング会社の1つのプロジェクトで働いており、DBAから、会社のベストプラクティスの状態ストアドプロシージャは「ベストプラクティス」ではないと言われました。これは、私が学んだすべてのことに非常に反しています。

ストアドプロシージャを使用すると、コードの再利用とカプセル化(ソフトウェア開発の2本の柱)、セキュリティ(個々のストアドプロシージャのアクセス許可を付与/取り消すことができます)、SQLインジェクション攻撃からの保護、および速度の向上(DBAによると、 SQL Server 2008以降では、通常のSQLクエリでさえ、十分な回数実行されるとコンパイルされます)。

アジャイルソフトウェア開発方法論を使用して複雑なアプリを開発しています。ストアドプロシージャを使用したくない理由を誰かが考えられるでしょうか。私の推測では、DBAはこれらのストアドプロシージャを維持することを望んでいませんでしたが、そのような設計上の決定を正当化するにはあまりにも多くのネガティブがあるようです。

152
user22453

非常に大規模なプロジェクトに携わった私の経験では、ビジネスロジックがどこに存在するかを非常に明確にする必要があります。個々の開発者がビジネスロジックをビジネスオブジェクトレイヤーまたはストアドプロシージャに適切に配置できる環境を許可すると、大規模なアプリケーションの理解と維持が非常に難しくなります。

ストアドプロシージャは、特定のDB操作を高速化するのに最適です。私のアーキテクチャ上の決定は、アプリケーションのビジネスレイヤーにすべてのロジックを残し、ストアドプロシージャを適切な方法で使用して、ベンチマークで保証されているパフォーマンスを向上させることです。

282
Eric J.

いくつかの観察

ストアドプロシージャは、コードの再利用とカプセル化(ソフトウェア開発の2本の柱)を提供します。

それらが使用されることになっているコンテキストでそれらを正しく使用する場合のみ。同じ主張は、関数(構造化プログラミング)またはメソッド(オブジェクト指向プログラミング)についても言えますが、1Kの関数と巨大なオブジェクトが見られます。

アーティファクトはあなたにそれらの利点を与えません。それらのアーティファクトの適切な使用はそれらの利点を与えるものです。

セキュリティ(個々のストアドプロシージャのアクセス許可を付与/取り消すことができます)、

はい。これは良い点であり、ストアドプロシージャが好きな主な理由の1つです。これらは、ビューとユーザーアカウントだけで通常達成できるものよりも細かいアクセス制御を提供します。

sQLインジェクション攻撃からユーザーを保護し、

パラメーター化されたSQLステートメントと入力スクラブで同じレベルの保護を実現できるため、これはSPに固有のものではありません。 「セキュリティの詳細」の問題として、これらに加えてSPを使用します。

また、速度の向上にも役立ちます(ただし、DBAは、SQL Server 2008以降、通常のSQLクエリでさえ、十分な回数実行されるとコンパイルされると述べています)。

これはデータベースベンダー固有ですが、一般的にはDBAが適切です。 SQLステートメント(静的またはパラメーター化)はコンパイルされます。 SPは、単純なSQLステートメントでは実行できないデータを集約および計算する必要がある場合に役立ちますが、SQLと緊密に統合されており、アプリサーバーへのラウンドトリップを保証しません。

良い例は、別のSQL自体を実行するための一時カーソルにデータをクエリすることです。アプリサーバーでプログラム的に行うことも、dbで行うことで複数のラウンドトリップを節約することもできます。

ただし、これは標準ではありません。これらのケースが多数ある場合、それはデータベース設計が悪いことを示しています(または部門間で互換性のないデータベーススキーマからデータを取得しています)。

アジャイルソフトウェア開発方法論を使用して複雑なアプリを開発しています。

敏捷性は、テクノロジーではなく、ソフトウェアエンジニアリングプロセスと要件管理に関係しています。

誰かがストアドプロシージャを使用したくない理由を考えることができますか?

間違った質問

質問は間違っており、「GOTOを使用しない理由はありますか?」この問題については、ダイクストラよりもニクラウスワースのほうが好きです。ダイクストラの感情がどこから来たのかは理解できますが、すべての場合に100%当てはまるとは思いません。 Store procやその他のテクノロジーと同じです。

ツールは、意図した目的にうまく使用でき、特定のタスクに最適なツールである場合に適しています。それ以外の場合は、ツールが間違っていることを示すものではありませんが、使用者は自分が何をしているのかを認識していません。

適切な質問は、「避けるべきストアドプロシージャの使用パターンの種類です。」または、」という条件です。ストアドプロシージャを使用する必要があります(または使用しないでください) "。理由を探るnotテクノロジーを使用することは、エンジニアリングの責任をエンジニアが属する場所に真っ直ぐに置くのではなく、単にツールに責任を負わせることです。

言い換えれば、それは警官隊または無知の表明です。

私の推測では、DBAはこれらのストアドプロシージャを維持することを望んでいませんでしたが、そのような設計上の決定を正当化するにはあまりにも多くのネガティブがあるようです。

そのとき彼らがしていることは、彼らが不十分に使用したツールに彼らの悪いエンジニアリング決定の結果を投影しています。

あなたの場合はどうしますか?

私の経験は、ローマにいるとき、ローマ人がするようにしてください

それと戦うな。あなたの会社の人々が、ストアプロシージャに悪い習慣を付けたい場合は、許可してください。ただし、これは彼らのエンジニアリング慣行において危険信号となる可能性があることに注意してください。

悪い習慣としての物事の典型的なラベル付けは、通常、無能なプログラマーがたくさんいる組織で行われます。特定の事柄をブラックリストに登録することにより、組織は自身の能力不足によって内部的に与えられる損害を制限しようとします。私はあなたをクソしない。

一般化はすべての失敗の母です。ストアドプロシージャ(または任意の種類のテクノロジ)は悪い習慣だと言って、それは一般化です。汎化は、無能な人のための警備員です。エンジニアはあからさまな一般化では機能しません。彼らはケースバイケースで分析を行い、分析のトレードオフを行い、問題を解決することになっているコンテキストで、目前の事実に従ってエンジニアリングの決定とソリューションを実行します。

優れたエンジニアは、このような一般化された方法で物事を悪い習慣として分類しません。彼らは問題を見て、適切なツールを選択し、トレードオフを行います。言い換えれば、彼らはエンジニアリングを行っています。

それらを使用しない方法についての私の意見

  • データ収集(およびおそらくいくつかの変換)を超えて複雑なロジックを入れないでください。データマッサージロジックをそれらに入れても、またはそれらを使用して複数のクエリの結果を集約します。しかし、それはそれについてです。それを超えるものは、別の場所にあるビジネスロジックと見なされます。

  • SQLインジェクションに対する防御の唯一のメカニズムとしてそれらを使用しないでください。それらをそこに残します何かが悪いためにそれらを引き起こす場合しかし、それらの前には防御ロジックがたくさんあるはずです-クライアント側の検証/スクラブ、サーバー側の検証/スクラブ、ドメインモデルで意味のある型に変換され、最後にパラメーター化されたステートメントに渡されます。 (パラメーター化されたSQLステートメントまたはパラメーター化されたストアドプロシージャである可能性があります。)

  • ストアプロシージャを含む場所をデータベースだけにしないでください。ストアプロシージャは、C#またはJavaソースコード。つまり、ストアプロシージャのテキストによる定義をソースコントロールします。ストアプロシージャをソースコントロールできないことを人々は認めています-ブルクラップ、彼らは話している血の地獄を知りません。

それらの使用方法/使用場所に関する私の意見

  • アプリケーションには、複数のクエリまたはビューから転置または集約する必要のあるデータが必要です。アプリケーションからデータベースにオフロードできます。ここでは、パフォーマンス分析を行う必要があります。a)これらのことを行う際に、データベースエンジンはアプリサーバーよりも効率的ですbut b)アプリサーバーは、(場合によっては)水平方向に拡張する方が簡単です。

  • きめ細かいアクセス制御。馬鹿なデカルト結合をdbで実行したくないが、そのような任意のSQLステートメントの実行を禁止することはできないどちらか。典型的な解決策は、開発環境およびUAT環境で任意のSQLステートメントを許可する一方で、systestおよび本番環境ではそれらを禁止することです。 systestまたは本番環境に移行する必要があるステートメントはすべて、ストアプロシージャに入り、開発者とdbasの両方によってコードレビューされます。

SQLステートメントを実行する有効な必要性notがストアプロシージャで実行されると、別のユーザー名/アカウントと接続プールが使用されます(使用状況は高度に監視され、推奨されません)。

  • Oracleのようなシステムでは、LDAPにアクセスしたり、外部データベースへのシンボリックリンクを作成したりできます(たとえば、vpnを介してビジネスパートナーのデータベースでストアプロシージャを呼び出す)スパゲッティコードを実行する簡単な方法ですが、それはすべてのプログラミングパラダイムに当てはまり、場合によっては、これが唯一のソリューションである特定のビジネス/環境要件があります。ストアプロシージャは、データの近くにあり、アプリサーバーに移動することなく、1つの場所だけでその美味しさをカプセル化するのに役立ちます。

これをストアプロシージャとしてdbで実行するか、アプリケーションサーバーで実行するかは、エンジニアとして行う必要があるトレードオフ分析に依存します。どちらのオプションも分析し、何らかの分析で正当化する必要があります。単に他の選択肢を「悪い習慣」として非難することによって、何らかの方法で進むことは、不十分なエンジニアリングの警備員です。

  • アプリサーバーを単純にスケールアップできない状況(つまり、新しいハードウェアまたはクラウドインスタンスの予算がない)が、dbに十分な容量がある場合バックエンド(これは多くの人が認めようとするより一般的です)、ビジネスロジックをストアプロシージャに移動するのにお金がかかります。美しくなく、貧血のドメインモデルにつながる可能性があります...しかし、再び...トレードオフ分析、ほとんどのソフトウェアのハックが吸い込むもの。

それが恒久的な解決策になるかどうかにかかわらず、それはその特定の瞬間に観察された制約に固有です。

それが役に立てば幸い。

172
luis.espinal

理論的根拠は、ストアドプロシージャレイヤーに依存すると、移植性が制限され、特定のDBに結び付けられることです。理由として追加の維持費も挙げられます。私はまたあなたが作ったこの点についてコメントしたいと思います:

(ストアドプロシージャ)SQLインジェクション攻撃からユーザーを保護する

保護するのは、実際にはパラメーター化されたクエリであり、プレーンテキストのSQLクエリで簡単に実行できます。

56
System Down

ストアドプロシージャがベストプラクティスではないことに同意する理由のいくつか。

  • ビジネスロジックとアプリケーションロジックは、データベースではなくコードに含める必要があります。 DBにロジックを配置することは、懸念を混同しています。
  • 残りのアプリケーションロジックでは、従来の単体テストプロジェクトのコードと同じくらいシームレスにストアドプロシージャをテストすることはできません。
  • コードを書いているとき、最初のプログラミングをテストするのに役立つストアドプロシージャが見つかりません。
  • ストアドプロシージャは、IDEでプログラムをデバッグするときに、アプリケーションコードほど簡単にはデバッグできません。
  • SP vs.通常のコードのバージョン管理/ソース管理
48
Gilles

ストアドプロシージャは、コードの再利用とカプセル化(ソフトウェア開発の2本の柱)を提供します。

はい。ただし、他のアジャイル設計目標を達成できるという犠牲を払って。一つには、それらを維持することはより困難です。私が取り組んでいるプロジェクトが何らかの兆候である場合、最終的には、本質的に同じ仕事をする複数の互換性のないSPになり、利益がなくなる可能性があります。

sQLインジェクション攻撃からユーザーを保護し、

いいえそうではありません。よく言われるように、私はこのアイデアがどこから来たのか推測することすらできず、それは単に真実ではありません。特定の種類のSQLインジェクション攻撃を軽減する可能性がありますが、最初にパラメーター化されたクエリを使用していない場合、それは問題になりません。 '; DROP TABLEアカウント; -

また、速度の向上にも役立ちます(ただし、DBAは、SQL Server 2008以降、通常のSQLクエリでさえ、十分な回数実行されるとコンパイルされると述べています)。

また、準備され、パラメーター化されたステートメントを使用すると、少なくともコンパイルされます(少なくとも、私が使用したいくつかのDBでは)。アプリケーションがクエリの実行を開始するとき(または、特に準備された同じクエリを複数回実行するとき)までに、SPにあると思われるパフォーマンス上の利点はまったくありません。

ストアドプロシージャIMHOを使用するonly理由は、複数の照合されたソースからプルする複雑なマルチステージクエリを作成する必要がある場合です。 SPには低レベルの決定ロジックを含めないでください。また、SPはneverを使用して、他の単純なクエリをカプセル化する必要があります。利点はなく、多くの欠点があります。

DBAの話を聞いてください。彼は何が起こっているのか知っています。

23
greyfade

SQL Serverを使用して、アプリケーションロジックのストアドプロシージャを使用している3社すべて。逆に実際に見たことはありません。しかし、私にとってそれらは大きな混乱です。ストアドプロシージャでのエラー処理機能やコードの再利用機能は、通常、あまり優れていません。

使用したいデータセットを返すストアドプロシージャがあるとします。それを将来のストアドプロシージャでどのように使用できますか?そのためのSQL Serverのメカニズムはあまり良くありません。 EXEC INTO ...は1つまたは2つのレベルのネストのみで機能します(今は忘れます)。または、作業テーブルを事前定義し、それをキー処理する必要があります。または、一時テーブルを事前に作成し、プロシージャに設定する必要があります。しかし、2人が同時に使用する予定がなかった2つの異なる手順で同じものを一時テーブルと呼ぶとどうなりますか?通常のプログラミング言語では、関数から配列を返すか、それらの間で共有されているオブジェクト/グローバル構造をポイントするだけです(グローバル構造を変更するだけでなく、データ構造を返す関数型言語を除く... )

コードの再利用はどうですか?一般的な式をUDF(またはさらに悪いサブクエリ)に入れ始めると、コードが遅くなります。ストアドプロシージャを呼び出して列の計算を実行することはできません(カーソルを使用し、列の値を1つずつ渡して、テーブル/データセットを何らかの方法で更新する場合を除く)。したがって、基本的に最高のパフォーマンスを得るには、メンテナンスの悪夢である場所全体に共通の式をカット/ペーストする必要があります...プログラミング言語を使用すると、共通のSQLを生成する関数を作成し、ビルド時にどこからでも呼び出すことができますSQL文字列。次に、数式を調整する必要がある場合は、1か所で変更できます...

エラー処理はどうですか? SQL Serverには、ストアドプロシージャの実行を直ちに停止する多くのエラーと、強制的に切断するエラーがあります。 2005年以降、try/catchが存在しますが、まだ捕捉できないエラーがいくつかあります。また、エラー処理コードのコードの複製でも同じことが起こり、ほとんどのプログラミング言語と同じくらい簡単に例外を渡したり、例外をより高いレベルにバブルしたりすることはできません。

また、速度だけです。データセットに対する操作の多くは、SET指向ではありません。行指向のものを行おうとすると、カーソルを使用するか、「カーソル」を使用します(開発者が各行を1つずつクエリして、カーソルと同じように内容を@変数に格納する場合)。 ..これは多くの場合、FORWARD_ONLYカーソルよりも低速ですが)。 SQL Server 2000では、1時間実行する前に何かを実行していました。そのコードをPerlで書き直したところ、20分で終了しました。 Cよりも20〜80倍遅いスクリプト言語がSQLのパフォーマンスを低下させる場合、SQLで行指向の操作を書くビジネスはまったくありません。

現在、SQL ServerにはCLR統合があり、CLRストアドプロシージャを使用すると、これらの問題の多くが解消されます。しかし、多くのDBAは、セキュリティ上の懸念から.NETプログラムを作成したり、CLRをオフにしたり、Transact SQLを使用したりする方法を知りません。 。

また、一般に、スケールアウトするのが最も難しいのはデータベースです。すべてのビジネスロジックがデータベース内にある場合、データベースが非常に遅くなると問題が発生します。ビジネスレイヤーがある場合は、キャッシュとビジネスサーバーを追加するだけでパフォーマンスを向上できます。従来、windows/linuxをインストールして.NET/Javaを実行する別のサーバーは、別のデータベースサーバーを購入してより多くのSQL Serverにライセンスを供与するよりもはるかに安価です。ただし、SQL Serverは現在、より多くのクラスタリングをサポートしていますが、もともと実際にはサポートされていませんでした。したがって、多額の資金がある場合は、クラスタリングを追加したり、ログ配布を行って複数の読み取り専用コピーを作成したりできます。しかし、全体としては、書き込みをキャッシュの背後に置くだけの場合よりもはるかにコストがかかります。

また、Transact-SQL機能も確認してください。文字列操作?私はJava String Class/Tokenizer/Scanner/Regex classes in any day。Hash Tables/Linked Lists/Etc。I'll take take the Javaコレクションフレームワークなど...そして.NETについても同じ... C#とJavaはどちらもTransact SQLよりもはるかに進化した言語です... Transact-SQLによるヘックコーディングは私を嫉妬させますC ...

さらに、ストアドプロシージャは、大きなデータセットを操作し、複数のクエリ/基準を適用して、ビジネスレイヤーに戻す前に縮小するためにより効率的です。大量のデータセットをクライアントアプリケーションに送信し、クライアントでデータを分解する必要がある場合は、サーバーですべての作業を行うよりもはるかに非効率的です。

また、ストアドプロシージャはセキュリティに優れています。基になるテーブルへのすべてのアクセスをカットし、ストアドプロシージャを介したアクセスのみを許可できます。 XMLのようないくつかの最新のテクニックを使用すると、バッチ更新を実行するストアドプロシージャを使用できます。その後、すべてのアクセスはストアドプロシージャを通じて制御され、データがより安全/正確である限り、データの整合性を維持できます。

SQLインジェクション引数は、プログラミング言語側でパラメーター化されたクエリを使用しているため、実際にはあまり適用されません。また、パラメーター化されたクエリの前でも、ほとんどの場合、少しのreplace( "'"、 "' '")も機能しました(ただし、文字列の末尾を超えて目的の結果を得るために使用するトリックはまだあります)。

全体として、SQLとTransact SQLは、データのクエリ/更新に最適な言語だと思います。ただし、任意のタイプのロジックをコーディングする場合は、文字列操作(またはファイル操作など)を実行してください。xp_cmdshellで実行できることに驚かれるでしょう...)いいえ。ストアドプロシージャをほとんど使用しない将来の場所を見つけたいと思っています。コードの保守性の観点から、それらは悪夢です。また、プラットフォームを切り替えたい場合はどうなりますか(実際にOracle/DB2/Sybase/Sql Serverなどを購入した場合は、独自の拡張機能を使用することで、プラットフォームを最大限に活用できます。 ..)。

また、驚いたことに、多くの場合、ビジネスロジックは同じではありません。理想的な世界では、すべてのロジックをストアドプロシージャに入れて、アプリケーション間で共有します。しかし、多くの場合、ロジックはアプリケーションによって異なり、ストアドプロシージャは非常に複雑なモノリスになり、人々は変更を恐れ、すべての影響を理解していません。一方、優れたオブジェクト指向言語では、各アプリケーションが独自のニーズにオーバーライドできる標準のインターフェイス/フックを備えたデータアクセスレイヤーをコーディングできます。

18
Cervo

これは、私が数年前にビッグファイブの1つで働いていたときの公式ラインです。理論的根拠は、SPは特定の実装(PL/SQL対T/SQL対...)に関連付けられているため、テクノロジーの選択を不必要に制限することでした。

T/SQLからPL/SQLへの1つの大きなシステムの移行を経験してきたので、私はその議論を理解できます。私はそれは少しお粗末なことだと思います-いくつの場所本当に気まぐれにあるデータベースから別のデータベースに移動しますか?

17
DaveE

サーバー上のストアドプロシージャのバージョン管理をどのように行いますか?

ストアドプロシージャをバージョン管理からサーバーに再展開すると、ストアドプランが実行できなくなります。

ストアドプロシージャはサーバー上で直接変更可能であってはなりません。それ以外の場合、実際に何が実際に実行されているかをどのようにして知ることができますか?そうでない場合、デプロイメントツールは、ストアドプロシージャをデータベースに書き込むためのアクセス権を必要とします。ビルドごとにデプロイする必要があります(実行計画は異なる必要がある場合があります)

ストアドプロシージャは移植性がありませんが、SQLも一般的には使用できません(Oracleの日付処理-uggghhhを参照)。

したがって、移植性が必要な場合は、内部データアクセスAPIを作成します。これは関数呼び出しのように呼び出すことができ、内部的にはパラメーター化されたクエリを使用して、必要な用語で組み込み、バージョン管理することができます。

12

これは、私が学んだすべてのことに非常に反しています。

あなたはもっと外に出る必要があるかもしれません。 [ニヤリと]真剣に、ストアードプロックは少なくとも10年間減少しています。 n層がクライアント/サーバーに置き換わって以来、ほとんどの場合。衰退は、OO Java、C#、Pythonなどの言語の採用によってのみ加速されています。

ストアドプロシージャに支持者や支持者がまだいないと言っているわけではありませんが、これは長期にわたる議論と議論です。それは新しいものではなく、おそらくかなり長い間続くでしょう。 IMO、ストアドプロシージャの対戦相手が明らかに勝利しています。

ストアドプロシージャは、コードの再利用とカプセル化を提供します(ソフトウェア開発の2本の柱)

とても本当です。しかし、適切に設計されたOOレイヤーもそうです。

セキュリティ(個々のストアドプロシージャのアクセス許可を付与/取り消すことができます)

あなたはそれを行うことができますが、深刻な制限のためにそれを行う人はほとんどいません。 DBレベルのセキュリティは、状況に応じた決定を行うのに十分な粒度ではありません。パフォーマンスと管理のオーバーヘッドのため、ユーザーごとの接続も珍しいので、アプリコードである程度の認証が必要です。ロールベースのログインを使用できますが、新しいロール用にそれらを作成し、実行しているロールを維持し、ロギングなどの「システムレベル」の機能を実行するために接続を切り替える必要があります。最後に、アプリの場合は所有されています-DBへの接続も所有しています。

sQLインジェクション攻撃から保護する

パラメータ化されたクエリを実行するだけです。とにかく必要とにかくやること。

また、速度の向上にも役立ちます(ただし、DBAは、SQL Server 2008以降、通常のSQLクエリでさえ、十分な回数実行されるとコンパイルされると述べています)。

それはMSSQL 7または2000で始まったと思います。ストアドプロシージャとインラインSQLのパフォーマンスに関する多くの議論、測定、および誤った情報がありました-私はすべてYAGNIにまとめました。そして、必要な場合はテストしてください。

アジャイルソフトウェア開発方法論を使用して複雑なアプリを開発しています。誰かがストアドプロシージャを使用したくない理由を考えることができますか?

したいにする理由は多くありません。 Java/C#/ any 3rd GL言語はすべて、カプセル化、再利用、および融通性などにおいてT-SQLよりはるかに優れています。そのほとんどは、まともなORMが与えられれば無料です。

また、「必要に応じて配布し、それ以上ではない」というアドバイスを与えてください-最近の証明の負担はSP擁護者にあると思います。storedprocを重いものにする一般的な理由は、T- SQLはOOよりも簡単で、店はOOよりも優れたT-SQL開発者です。または、DBAがデータベースレイヤーで停止し、ストアドプロシージャが開発者とDBA間のインターフェイスです。または、セミカスタムを出荷しています製品やストアドプロシージャはユーザーがカスタマイズできます。そのような考慮事項がなければ、最近のアジャイルソフトウェアプロジェクトのデフォルトはORMになると思います。

9
Mark Brackett

上記のすべてのケースを考慮して、もう1つ追加したいと思います。 SPの選択は、人々の選択にも依存する場合があります。

私が個人的にSPに非常に複雑なロジックを配置すると、私はそのようなSPは保守とデバッグが非常に複雑であると信じています。開発者自身が直面する多くの場合でもコードビハインド(たとえば、言語部分)でデバッグするときの問題は、SPよりもはるかに簡単です。

SPは単純な操作にのみ使用してください。まあそれは私の選択です。

4
Rimbik

ストアドプロシージャに関するいくつかの問題と問題の両方をカバーしたいと思います。私たちはそれらを LedgerSMB で幅広く使用しており、私たちのルールは、いくつかの非常に具体的な拡張を使用して、「クエリの場合はストアドプロシージャにする」です。

これを行う理由は、言語を超えたクエリの再利用を容易にするためでした。これを正直に行うためのより良い方法はありません。

最後に、質問は常に詳細にあります。よく使用されたストアドプロシージャは、物事を非常に簡単にします。

ではコン側に。

  1. 伝統的に使用されているように、ストアドプロシージャは脆弱です。単独で使用すると、呼び出し構文が変更された以外に理由もなく予期しない場所でコードにバグが追加される可能性があります。単独で使用すると、これは少し問題になります。レイヤー間の凝集度が高すぎるため、問題が発生します。

  2. はい、動的SQLを実行する場合は、Sproc内のSQLインジェクションを使用できます。この領域に自信が持てないことは悪いことであり、その結果、この領域のセキュリティに関する重要な経験が必要になります。

  3. インターフェースの変更は、上記の理由#1のストアドプロシージャでやや問題がありますが、多数のクライアントアプリが関係している場合、これは非常に大きな悪夢になる可能性があります。

上記は否定するのがかなり難しいです。彼らが起こる。誰もが、プロSPとアンチSPはおそらくこれらについて恐怖の物語を持っています。問題は解決できないわけではありませんが、注意を払わなければ解決できません(LedgerSMBでは、サービスロケーターを使用して、実行時に動的にSP呼び出しを構築し、上記の問題はすべてPostgreSQLのみですが、他のデータベースでも同様のことが可能です。

ポジティブに移ります。上記の問題を解決できるとすると、次のようになります。

  1. 集合演算の明瞭度が向上する可能性。これは、クエリが非常に大きいか、非常に柔軟な場合に特に当てはまります。これは、テスト容易性の向上にもつながります。

  2. この領域ですでにサービスロケータが動作している場合、ストアドプロシージャを使用すると、アプリケーション開発者がデータベースの問題から解放され、逆も同様であるため、開発のペースが速くなります。これは正しいことを行うのにいくつかの困難がありますが、それを行うことはそれほど難しくありません。

  3. クエリの再利用。

おお、そしてあなたがSPでほとんど決してすべきでないいくつかのこと:

  1. 非トランザクションロジック。注文が発送されたが、トランザクションがロールバックされたという電子メールを送信しました...または今、電子メールサーバーがオンラインになるのを待機しています...または、さらに悪いことに、メールサーバー..。

  2. プロシージャロジックが散りばめられた、緩やかに結合された多数の小さなクエリ...

4
Chris Travers

データベースのブランドを切り替えて同じストアドプロシージャを利用するのは非常に困難です。

あなたのチームにはDBAがいないので、SQLに関係することは他にありません。

これは、プログラマv DBAの放尿コンテストにすぎません。

3
JeffO

誰のために働いていますか?

答えは、あなたが雇用している人、コンサルティング会社、または会社自体によって異なります。企業にとって最善のことは、コンサルティング会社や他のソフトウェアベンダーにとっては最善ではないことがよくあります。例えば賢い会社は、競争相手よりも永続的に優位に立つことを望んでいます。対照的に、ソフトウェアベンダーは、同じソリューションを特定の業界のすべての企業に最低限のコストで提供できることを望んでいます。彼らがこれで成功した場合、クライアントにとって正味の競争上の優位性はなくなります。

この特定のケースでは、アプリケーションが行き来しますが、多くの場合、企業データベースは永遠に存続します。 RDBMSが行う主なことの1つは、ジャンクデータがデータベースに入らないようにすることです。これには、ストアドプロシージャが含まれる場合があります。ロジックが適切であり、年ごとに変更される可能性が非常に低い場合、データベースを使用するように作成されたアプリケーションに関係なく、なぜそれがデータベース内に存在せず、内部的に一貫性を保つ必要があるのでしょうか。数年後、誰かがデータベースについて質問したい質問があり、ジャンクがDBに入るのを阻止されていれば、それは答えられます。

したがって、おそらくこれは、DBAがコンサルティング会社で働いているという事実と関係があるのか​​もしれません。コードを移植できるほど、クライアント間でコードを再利用できます。彼らが彼らのアプリで結び付けることができるより多くのロジック、より多くの会社はベンダーと結婚します。彼らがその過程で大きな混乱を残した場合、彼らはそれを片付けるために報酬を受け取るか、再び混乱を見ることがありません。どちらにしても、それは彼らにとって勝利です。

enter image description here

フェンスの両側の(たくさんの)より多くの議論については、 coding horror での議論を読んでください。 FWIW私はSPを擁護する人々の側に寄りかかっています。

3
user21007

プログラミングソロ、ストアドプロシージャの書き込みに抵抗できません

主にMySQLを使用しています。以前はPostGreSQLのようにオブジェクト指向データベースを使用したことがありませんが、MySQLのSPで実行できることは、テーブル構造を少し抽象化することです。 SPを使用すると、入力と出力が変更されない、その下のデータベースであっても、これらのプリミティブアクションを設計できます変化します

ですから、logInというプロシージャがあります。ログインするときは、常にusernamepasswordを渡すだけです。返される結果は整数userIdです。

logInがストアドプロシージャの場合、ログイン時に最初のログインと同時に行われる追加の作業を追加できるようになりました。ストアドプロシージャにロジックが埋め込まれた一連のSQLステートメントを見つけました書き込みが簡単(呼び出し環境FETCH)->(結果を取得)->(呼び出し環境FETCH)シリーズよりも、ロジックを記述するときに行う必要がありますサーバ側。

2
bobobobo

異なるプログラミング言語を使用して、ビジネスロジックを異なるレイヤーに分割することは、常に問題の原因です。世界を切り替える必要がある場合、バグの追跡や変更の実装は非常に困難です。

とは言っても、データベースにあるPL/SQLパッケージにallビジネスロジックを入れることでかなりうまくいく企業は知っています。これらは非常に大きなアプリケーションではありませんが、些細なことでもありません。 20K-100K LOCと言います。 (PL/SQLはT-SQLよりもこの種のシステムに適しているため、T-SQLしか知らない場合は、おそらく信じられないことに頭を悩ませるでしょう...)

2
user281377

これはまだ言及されていない別のポイントです:

コード生成ツールとリバースエンジニアリングツールは、ストアドプロシージャにうまく対応できません。ツールは通常、プロシージャが何を実行するかを認識できません。プロシージャは結果セットを返しますか?複数の結果セット?複数のテーブルと一時テーブルから結果セットをフェッチしますか? procはカプセル化された更新ステートメントだけで何も返しませんか?結果セット、戻り値、およびいくつかの「コンソール出力」を返しますか?

したがって、データ転送オブジェクトのDTOおよびDAOレイヤーを自動的に作成するツール(liferayの「サービスビルダー」など)を使用する場合は、簡単に作成できません。

さらに、データソースがSPの場合、HibernateのようなORMは実際には正しく機能しません。データアクセスはせいぜい読み取り専用です。

2
knb

IMO依存します。ストアドプロシージャはその場所にありますが、ベストプラクティスではありません。賢い開発者は、特定の状況を適切に評価し、ストアドプロシージャがその答えであるかどうかを判断する方法を知っています。個人的には、ストアドプロシージャではなく、ある種のORM(生のLinqからSqlのような基本的なものも含む)を使用するのが好きです。

2
Wayne Molina

コミュニティーがかなり長い間、ストアード・プロシージャーから遠ざかっているというマークに同意します。元のポスターでSPを使用する理由が指摘されたポイントの多くは一度に有効でしたが、かなり前からあり、別のポスターで述べられているように、環境は変化しています。たとえば、SPを「昔に」使用するための1つの議論は、実行計画が「事前コンパイル」されていた一方で、コードからの動的SQLを実行ごとに「再コンパイル」する必要があったために達成されたパフォーマンスの向上でした。主要なデータベースが変更、改善、適合などされたため、これは当てはまりません。

つまり、現在のプロジェクトではSPを使用しています。その理由は、レガシーアプリケーションを引き続きサポートする既存のデータベースの上に新しいアプリケーションを構築しているからです。その結果、レガシーアプリをオフにするまで、スキーマの変更は非常に困難です。アプリケーションに必要な動作とルールに基づいて新しいアプリケーションを設計し、SPを使用して一時的にデータベースとやり取りし、SPが既存のSQLに適応できるようにすることを意識的に決定しました。これは、SPがアプリケーションコードの変更を必要とせずにデータベースレベルでの変更を容易にするという以前の投稿者のポイントに行きます。アダプターパターンの実装としてSPを使用することは確かに私にとって(特に、現在のプロジェクトを考えると)意味があり、今日の使用について私が本当に見ることができる唯一の議論かもしれません。

Fwiw、スキーマが更新されたときにSPを削除することを意図しています。しかし、企業開発の他のすべてと同様に、それが起こるかどうかを確認します! [ニヤリ]

1
SonOfPirate

ストアドプロシージャはサーバーのCPU時間を使用することも指摘しておきます。それほど多くはありませんが、いくつかあります。作業手順で行われた作業の一部はアプリで行うことができます。データレイヤーよりもアプリレイヤーをスケーリングする方が簡単です。

1

ストアドプロシージャの使用方法を簡潔に概説したかっただけです。私はそれらが全く悪い習慣だとは思いません、そして他の人がそうであるようにそれらは適切な状況で使用されるべきであると言いました。

さまざまなアプリケーションのプロシージャを作成すると、機能がわかりにくくなり、アプリケーションのビジネスロジックが分離されて、データベースがさらに整理されて制限されるという問題が発生します。

したがって、データベース固有のリレーショナルデータ指向のタスクでは、ストアドプロシージャを使用します。つまり、アプリケーションのデータと一致するデータベース操作に使用されるロジックがある場合、データを一貫して保存するためにストアドプロシージャを使用できます(理にかなっています)。これの良い例は次のとおりです。一貫したロギング、一貫したメンテナンス、機密情報の操作など

データベースの強力なデータモデルに従うアプリケーションのニーズに合わせてデータを操作する他のタスクは、ビジネスロジックを含む別のレイヤーに保存する必要があると思います。要するに、整合性のためのデータベース固有のデータ操作では、整合性がデータベース整合性スキーマモデルを超えて拡張されるストアドプロシージャを使用できます。

0
Mark