ストアドプロシージャのビジネスロジックに対する賛否両論は何ですか?
ストアドプロシージャに対して:プログラミングスペースのビジネスロジック
私は表現力を重視していますが、SQL空間がそれほど表現力に富んでいるとは思いません。最も適切なタスクには、手元にある最高のツールを使用してください。ロジックや高次の概念をいじるのは、最高レベルで行うのが最適です。したがって、ストレージと大量のデータの操作は、おそらくストアドプロシージャで、サーバーレベルで行うのが最適です。
しかし、それは状況によって異なります。複数のアプリケーションが1つのストレージメカニズムと相互作用していて、その整合性とワークフローを確実に維持したい場合は、すべてのロジックをデータベースサーバーにオフロードする必要があります。または、複数のアプリケーションでの並行開発を管理する準備をしてください。
私は完全に反対しています。最大の理由の1つは、earinoが述べた最初の理由です-それは1つの場所に住んでいます。ソース管理に簡単に統合することはできません。 2人の開発者がストアドプロシージャで同時に作業することはほぼ不可能です。
私の他の主な不満は、SQLは複雑なロジックを表現するのがあまり得意ではないということです。スコープの概念はありません。コードを再利用する機能が少ないため(OO言語)とは対照的に)、コードはコピーアンドペーストされる傾向があります。
データベースを開発するには、開発者にデータベースへのアクセスを許可する必要があります。私がデータで働いてきた多くの組織では、人々は開発者とは異なる世界にいて、異なる権限などを持っています。このような場合、開発者をデータベースから除外することは困難です。
私は、ビジネスロジックがある限り、次のように言っている学派です。
ロジックがストアドプロシージャ、J2EE中間層、クリップエキスパートシステム、またはその他の場所にあるかどうかは関係ありません。私たちのビジネスロジックをどこに保存しても、「悲惨さの保存則」は、コンポーネント/リポジトリXをテクノロジー/メソッドYに交換する必要があるため、誰かがそれが間違った考えであると言うことを保証します。
いくつかの考え:これはJava中心の応答ですが、最近(過去10年間)の経験の大部分であることに注意してください
(1)(大規模な)開発者チームによる並行開発。アプリケーションが十分に複雑で、各開発者が独自のプライベートバージョンのDBをセットアップできない場合(リンク/参照データなどに参加)、開発者のチーム全体で作業することは非常に困難です。同じPL-SQL(たとえば)パッケージのセットが同時に共有DEVL DBに格納されていますか?次に、無効なプロシージャを使用してDBで作業することで立ち往生している(私の経験)/人々が変更を加えるときにコードがテーブルに一致しない...
Javaアーキテクトとして、各開発者がデスクトップにプライベートJBossインスタンスを持ち、独自の機能セットで簡単に作業し、全員に影響を与えることなく独自のペースで統合する方がはるかに簡単だと思います。それ以外の場合...これにより...
(2)継続的インテグレーションツールセットDBの世界には同様の「概念」がいくつか存在しますが、私の経験では、次の組み合わせが示されています(ここでは、現在の最高のお気に入りを選択しています)。
上記のすべて(無料のツール)を使用して大規模なプロジェクトを実行すると、一貫性のある簡単な方法でXPを大衆に提供し、ITスタッフ全体に品質管理を実施できます。Oracle/ PL-SQLは、一致するツールセットがありません
(3)ツール/ライブラリなど... Javaは、他のプラットフォームではアクセスできない驚くべきサービスのセットにアクセスできます。無料のものもあれば、そうでないものもあります。log4jのような基本的なサービスもあります(そうです。 PL/SQL用に用意されていますが、please ...ほぼ同じではありません)、開発者がその場で変更できる柔軟に調整可能なロギングを作成できるようにするなどのことができます(ダバグに最適です)。自動APIドキュメント(javadoc経由)。自動化されたユニットテストカバレッジレポート。統合されたプログラマーを備えた信じられないほどのIDE(Eclipse)/アプリサーバーへの自動デプロイ。Sunの下であらゆるタイプのサービスとインターフェイスするAPI、あらゆることを行うオープンソースライブラリ、すべてのベンダーによる100%サポート
(4)サービスの再利用。誰かがコメントしたことは真実です。ヘビーデューティーデータ駆動型ビジネスルールの場合、これらはDBレイヤーに存在する必要があると主張できます。どうして?中間層がすべてそのロジックを複製する必要がないようにするため。
しかし、同じことがビジネスルールにも言えますデータ駆動型ではないか、OOがより自然な選択です)==。すべてのビジネスロジックをDBに固定する場合、その後、DB経由でのみ利用可能です。
私
retCode = validateSomeDate(date);
if (retCode == 1) then
evaluateIfCustomerGetsEmail(...)//probably more stored proc invocations here...
sendEmailMsg(....)
else if (retCode == 2) then
performOtherBizLogicStuf(...) //again, may need data, may not need data
triggerExternalsystemToDoSomething(...) //may not be accessible via PL/SQL
fi
上記のように作成されたシステムをすべて見て、午前2時にデバッグする必要があったと確信しています。ビジネスロジックが階層間で断片化されている場合、複雑なプロセスの一貫した感覚を得るのは非常に困難であり、場合によっては維持することが不可能になります。
「それをソース管理に簡単に統合することはできません。」 -ストアドプロシージャを作成するコードをバージョン管理されたスクリプトに入れると、その異論はなくなります。 Scott Amblerのアジャイルデータベースのアイデアに従う場合、それはまさにあなたがすべきことです。
すべての開発者が優れたデータモデラーであるとは限りません。 SQLについてのちょっとした知識が彼らをデータベースの専門家にしたと思った開発者によって作成された恐ろしいスキーマを考えることができます。開発者がDBAやデータモデラーと協力することには多くの価値があると思います。
データベースを使用するアプリケーションが1つだけの場合、ビジネスロジックは中間層に表示される可能性があります。多くのアプリがデータベースを共有している場合は、データベースに配置することをお勧めします。
SOAは中道を提供します:サービスはデータを所有します。サービスのみがデータにアクセスできます。データを取得するということは、サービスを利用することを意味します。その場合、どちらの場所にもルールを配置することができます。
アプリケーションは行き来しますが、データは残ります。
ビジネスロジックをsprocsに格納しないもう1つの理由-DBのスケーリング機能が制限されています。データベースがボトルネックになるのは非常に一般的な状況です。そのため、DBの負荷をできるだけ多く取ることをお勧めします。
私のいくつかの観察:
ストアドプロシージャを支持する:
プロジェクトが終了した後、ほとんどの場合、ボトルネックはWebサーバーではなくデータベースであり、ストアドプロシージャははるかに高速です。
oRMで生成されたSQLクエリでSQLプロファイラーを使用することは非常に困難です。これはストアドプロシージャで簡単です
サービスウィンドウなしで、ストアドプロシージャの修正を即座にデプロイできます
パフォーマンスのために、ORMコードよりもストアドプロシージャを最適化する方が簡単です
同じdb /ストアドプロシージャを使用する多くのアプリケーションがあるかもしれません
複雑なデータシナリオは、ストアドプロシージャへの投票です
アプリケーション/ ORMを支持して:
コードリポジトリを使用できます(ストアドプロシージャを使用することは可能ですが、費用がかかります)
Java/c#言語は、ビジネスロジックを表現するための優れたツールです
Java/c#はデバッグが簡単です(動的に生成されたORM sqlを除く)
データベースエンジンの独立性(ただし、プロジェクトがデータベースを別のデータベースに変更する可能性はほとんどありません)
ORMは使いやすいデータモデルを提供します
私の意見では、大規模なプロジェクトの場合は、ストアドプロシージャを使用し、その他の場合は、アプリケーション/ ORMは正常に機能します。
結局のところ、重要なのはデータベースだけです。
ビジネスロジックは1か所にカプセル化する必要があります。ロジックが常に実行され、一貫して実行されることを保証できます。データベース上のエンティティに関連するすべてのアクティビティを実行する必要があるクラスを使用すると、すべての検証が正しく実行されることが保証されます。このコードには1つの場所があり、プロジェクトの開発者は誰でもこのクラスを簡単に開いてロジックを確認できます(ドキュメントは古くなる可能性があり、古くなる可能性があるため、コードは唯一の信頼できるドキュメント形式です)。
これは、ストアドプロシージャでは困難です。同じテーブルを処理する複数のsprocがある場合があります。複数のsprocをチェーンして、ロジックが1つだけに存在するようにすると、扱いにくくなります。それがストライキ1です。データベース内の「エンティティXを取り巻くすべてのビジネスルールは何ですか」をどのように判断しますか?それを追跡しようとしている何千ものsprocを検索して楽しんでください。
2つ目は、ビジネスロジックを永続化メカニズムに結び付けていることです。すべてのデータを同じデータベースに保存したり、一部をXMLなどに保存したりすることはできません。このタイプの不整合は開発者にとって困難です。
ロジックがデータベースにのみ存在する場合、検証を実行するのは困難です。データ入力フォームのすべてのフィールドを検証するために、本当にsprocを呼び出しますか?検証ルールとビジネスロジックは密接な関係にあります。このロジックはすべて同じ場所で実行する必要があります。
ことわざがあります...
ハンマーだけを持っていると、すべてが釘のように見えます。
私の謙虚な意見では、すべての状況に適合する答えは1つではありません。多くの人は、ビジネスロジックをデータベースに入れるのは常に間違っていると思っているようです。
データベース側で実行すると、トランザクション処理、特に一括操作を非常に効率的にするために多くの作業が行われました。また、データベースに対する意見のほとんどが形成されて以来、データベースのコード管理は大幅に改善されました。
データベースサーバーを単なる永続層と見なすのは間違っていると思います。 DBサーバーで実行したときに処理アクティビティが最も効率的である場合は、そこで実行します。
そうでない場合は、他の場所でそれらを行います。
それはすべて、あなたが現在取り組んでいるアプリケーション、あなたが働いているチーム、そしてあなたを雇った顧客に最も適したものに帰着します。
それはちょうど私の2セントです。
+:SQLサーバーがコードを最適化することがある
+:パラメータを渡す必要があるため、SQLインジェクションの問題が制限されます
-:コードは単一のデータベースに依存しています(一部のデータベースにはSPさえありません)
-:コードを変更するには、データベースに接続する必要があります
-:ロジックがうまく整理されていません
個人的には反対ですが、忙しいウェブサイトで一度使用しなければなりませんでした。 MSSQLでSPを使用すると、大きなメリットがありますが、キャッシュを実装すると、それらのメリットはそれほど大きくなくなりました。
ビジネスロジック層にある場合は、ビジネスロジックを単体テストできます。完全に分離されている場合は、永続化操作をモックできるため、BLのみをテストします。ストアドプロシージャは、メンテナンス/デバッグ/単体テストよりもはるかに困難です。 linqとc#。
「ビジネスロジック」にはさまざまな種類があります。他のレイヤーやサービスとの関係に基づいてパーティション化することを検討してください。 MVCの観点からの経験則は次のとおりです。
a)データベース(ストアドプロシージャ)で、ほとんどがデータ関連であり、結合と比較的単純なWHEREおよびSELECT句を使用して実行できる場合。
b)コントローラー内で、ほとんどがルーティングまたはディスパッチに関連している場合。つまり、画面またはリソースの選択に関する大規模なUIフロー制御です。
c)モデルまたはビューモデルで、複雑または複雑な計算や条件が含まれる場合。
d)ビュー(Razorなど)で、主に「使いやすい」再フォーマットなどの表示の問題であり、実装が比較的簡単な場合。 (複雑な場合は、ビューモデルに配置することを検討してください。)
DBMS!=アプリケーションサーバー
ビジネスロジックのストアドプロシージャは、今日では悪い習慣です。代わりに3層アーキテクチャを使用してください。
@Nick「私は完全に反対しています。最大の理由の1つは、earinoが述べた最初の理由です。1つの場所にあります。ソース管理に簡単に統合することはできません。2人の開発者が作業することはほぼ不可能です。同時にストアドプロシージャ。」
ストアドプロシージャにビジネスロジックを配置することを主張しているわけではありません(すべて逆です)。しかし、あなたが提唱したこれらの理由は意味がありません。ストアドプロシージャは、ソース管理に保存できる単なるsql/DDLアーティファクトであり、デプロイメントアーティファクトでもあります(つまり、戦争/耳を渡すのとほぼ同じ方法で、デプロイメントのためにdbaに渡されるものです。 IT /デプロイメントリエゾンへのアーティファクト)1人以上の開発者は、ブランチ、バージョン管理、およびマージによって、従来のソースコードで行うのとまったく同じ方法で、ソース管理から離れた同じストアドプロシージャで作業できます。
さて、ストアドプロシージャ(およびそれらを含むパッケージ)の唯一のコピーがデータベースにのみ存在する場合、ソース管理(およびそれに関連するすべての問題)でそれを制御することはできません。ただし、これはストアドプロシージャの問題ではなく、そのコードの使用方法に関する不適切な問題です。これは、ソースコードのコピーが1つだけ本番環境に存在するのと同じように不適切な表示です。
JavaとPLSQL/DDLの両方で、大量のコードを含むシステムで作業しましたが、すべてクリアケースでバージョン管理されていました。これらはすべて、コンパイルおよびデプロイされるソースコードとして扱われました。厳格なプロセスで、さまざまなチームが取り組んでいます。あなたが説明していることとして問題はありませんでした。
コンテキスト固有ストアドプロシージャにビジネスロジックを配置しない理由がありますが、これらは有効なものではありません。
特に明示的なトランザクションが含まれる場合は、ロジックをストアドプロシージャに移動することで、パフォーマンスが大幅に向上します。
私の経験では、アプリケーション開発者は最適化されたデータベースコードを書くのが苦手で、並行性やパフォーマンスの問題について考える傾向がありません。
ビジネスロジックがアプリケーション層に保持されている場合、ネットワーク全体で大量のデータをシフトし(多くの場合、多くのラウンドトリップで)、DBサーバーのメモリに複製し、少なくとも1回は複製する必要があります。アプリサーバーで、トランザクションを開いたままにして、アプリで行ごとの処理をロードします。次に、アプリ開発者はデータベースが遅く、デッドロックを続けていると不平を言います。
可能な限りロジックをDBに配置すると、ネットワークを介していくつかのパラメーターを渡す傾向があり、ネットワークリソースを待機している間はトランザクションが保持されず、すべてが稲妻のようになります。もちろん、データベースは他のソースコードと同じようにソース管理に入る必要があります。そのためのツールはたくさんあります。
私の大まかなルールは(質問について考えてそれが何であるかを認識した後)、ストアドプロシージャに特定のデータの挿入、削除、変更を禁止するか、その他の必要な変更を加えるかにかかわらず、データベース内のデータの整合性を保証するコードを含める必要があるということです。データの整合性のため。ビジネスロジック、特に少数のセットベースの操作では実装できないロジックは、他の場所で実装する必要があります。データベースはアプリケーションではありません。データベースは、関係と制約の最終的な権限である必要があります。たとえば、Webサーバーからのポストバックを減らしたり、ビジー状態のサーバーでの不要なヒットを排除したりするユーザーインターフェイスコードでのフィードバックの提供など、ビジネスルールが他の場所でも実装されている場合でも同様です。 「データの整合性」に複雑なビジネスルールの複雑な処理の結果が含まれるかどうかは議論の余地がありますが、コンテキストが理解されれば、通常は明らかだと思います。すべてのビジネスルールがデータの関係または制約として実装されているわけではありません。ストアドプロシージャのすべての操作が、ネットワーク上の別のマシンで実行されているプロセスであっても、別のプロセスで実行されているコードよりも高速であるとは限りません。私は最近、SSISの多くの操作、たとえば(INSERT INTO()SELECT FROM)が、ストアドプロシージャで実行するよりも、別のマシンのネットワーク上で実行されるSSISで高速に実行されることを示すデモを行いました(結果をデータベースに挿入します)。ネットワーク全体)。これはほとんど信じられない結果であり(SSISは生のSQLステートメントよりも高速です)、パフォーマンスの問題の最良の最適化の発見は、いくつかの概念のみに基づくロジックからではなく、現実(テスト)からもたらされることを示しています。 (経験則によって何をテストするかを決定する必要があります。)(SSISは、マルチスレッドとパイプラインを自動的に実装し、生のSQLステートメントで指定されていない場合でもBULK INSERTを使用し、バッチを送信することで、より高速に実行されました。他のスレッドで追加のBULKINSERTを作成しながら、1つのスレッドで挿入を行います。この場合、生のSQLステートメントの約2倍の速度で実行されました。)プログラミングとSQL Serverのコースを教えていたとき、PowerBuilderユーザーは「ネイティブ」というステートメントを持っているようでした。ドライバーは彼らの舌に焼き付けられた「最速のデータアクセスを提供します」、そしてそれは追加の(彼らによって認識されていない)説明を通して正当化されるかもしれませんが、その背後にある考え方は誤解を招きます。
高予算のプロジェクト:最新のデータをメモリに保持し、変更を定期的にディスクに保存する場合は、データベースサーバーとは別にビジネスロジックを処理する必要があります。ユースケース:RAM、複雑なキャッシュメカニズムからデータを提供します。
低予算のプロジェクト:ディスク上の最新のデータを保持していて、プレゼンテーションがディスクの読み取りに依存している場合、ストアドプロシージャでビジネスロジックを処理すると、開発時間を節約できます。ユースケース:ディスクからデータを提供する