古くからの質問。ビジネス ロジックは、ストアド プロシージャ (またはパッケージ) としてのデータベース内、またはアプリケーション/中間層のどこに配置する必要がありますか? さらに重要なことは、なぜですか?
データベースの独立性は目標ではないと仮定します。
古くからの質問。ビジネス ロジックは、ストアド プロシージャ (またはパッケージ) としてのデータベース内、またはアプリケーション/中間層のどこに配置する必要がありますか? さらに重要なことは、なぜですか?
データベースの独立性は目標ではないと仮定します。
ビジネス ロジックをどこに配置するかを決定する場合、コードの保守性は常に大きな懸念事項です。
一般に、統合されたデバッグ ツールとより強力な IDE を使用すると、ストアド プロシージャ内の同じコードよりも中間層コードの保守が容易になります。特に理由がない限り、ストアド プロシージャではなく、中間層/アプリケーションのビジネス ロジックから始める必要があります。
ただし、レポートやデータ マイニング/検索に関しては、多くの場合、ストアド プロシージャの方が適しています。これは、データベースの集約/フィルタリング機能のパワーと、データ ソースに非常に近い処理を維持しているという事実のおかげです。しかし、これはいずれにせよ、ほとんどの人が古典的なビジネス ロジックと見なすものではないかもしれません。
データベースに十分な量のビジネス ロジックを配置して、データの一貫性と正確性を確保します。
ただし、ユーザー エクスペリエンスを向上させるために、このロジックの一部を別のレベルで複製する必要があることを恐れないでください。
非常に単純なケースでは、ビジネス ロジックをストアド プロシージャに入れることができます。通常、単純なケースでさえ、時間の経過とともに複雑になる傾向があります。ビジネス ロジックをデータベースに含めない理由は次のとおりです。
ビジネス ロジックをデータベースに配置すると、データベースの技術的な実装と密接に結び付けられます。テーブルを変更すると、多くのストアド プロシージャを再度変更することになり、多くの追加のバグと追加のテストが発生します。
通常、UI は検証などのビジネス ロジックに依存します。これらのものをデータベースに入れると、データベースと UI の間に密結合が発生するか、場合によっては、これら 2 つの間の検証ロジックが重複します。
複数のアプリケーションを同じデータベースで動作させるのは難しくなります。1 つのアプリケーションを変更すると、他のアプリケーションが壊れます。これはすぐにメンテナンスの悪夢に変わる可能性があります。したがって、実際にはスケーリングしません。
より実際には、SQL は、ビジネス ロジックを理解しやすい方法で実装するのに適した言語ではありません。SQL はセット ベースの操作には優れていますが、大量のストアド プロシージャを維持するのが難しい「大規模なプログラミング」のための構造が欠けています。現代の OO 言語は、これにより適していて、より柔軟です。
これは、ストアド プロシージャとビューを使用できないという意味ではありません。テーブルとアプリケーションの間にストアド プロシージャとビューのレイヤーを追加して、2 つを分離することをお勧めします。そうすれば、外部インターフェイスを変更せずにデータベースのレイアウトを変更して、データベースを個別にリファクタリングできます。
一貫性がある限り、それは本当にあなた次第です。
これをデータベース層に配置する正当な理由の 1 つは、クライアントがデータベースのバックエンドを決して変更しないと確信している場合です。
アプリケーション層に配置する正当な理由の 1 つは、アプリケーションで複数の永続化テクノロジをターゲットにしている場合です。
また、コア・コンピテンシーも考慮に入れる必要があります。あなたの開発者は主にアプリケーション層の開発者ですか、それとも主に DBA タイプですか?
アプリケーション層にビジネスロジックを配置することには確かに利点がありますが、言語/フレームワークはデータベースよりも頻繁に変更されるように思われることを指摘したいと思います。
私がサポートしているシステムのいくつかは、過去10〜15年間に次のUIを使用していました。OracleForms/ Visual Basic / Perl CGI / ASP/Javaサーブレット。変更されなかったのは、リレーショナルデータベースとストアドプロシージャです。
データの整合性に影響するものはすべて、データベース レベルに配置する必要があります。ユーザー インターフェイス以外にも、インポート、価格体系を変更するための一括更新、ホット フィックスなど、データベースへのデータの挿入、データベースからのデータの更新または削除がよく行われます。ルールが常に守られていることを確認する必要がある場合は、ロジックをデフォルトに設定します。とトリガー。
これは、ユーザーインターフェイスにもそれを含めるのが良い考えではないと言っているわけではありません (データベースが受け入れない情報を送信する必要があるのはなぜですか)。
プロジェクトによって異なりますが、正解は 1 つではありませんが、Eric Evans による「 Domain Driven Design 」で提唱されているアプローチをお勧めします。このアプローチでは、ビジネス ロジックは独自のレイヤー (ドメイン レイヤー) に分離されます。ドメイン レイヤーは、インフラストラクチャ レイヤーの上にあり、データベース コードを含めることができ、アプリケーション レイヤーの下にあり、リクエストをドメイン レイヤーに送信します。フルフィルメントを確認し、完了の確認をリッスンして、アプリケーションを効果的に推進します。
このように、ビジネス ロジックは、技術的な問題は別として、ビジネスを理解している人と議論できるモデルに取り込まれ、ビジネス ルール自体の変更、技術的な実装の問題、およびプロセスの流れを分離しやすくなります。ビジネス (ドメイン) モデルと対話するアプリケーション。
この純粋な理想が実際のコードやプロジェクトの現実の世界で実際にどのように近似されるかを説明するのに非常に優れているため、機会があれば上記の本を読むことをお勧めします.
この場合、質問者が考慮事項として除外するデータベースの独立性は、データベースからロジックを取り除くための最も強力な議論です。データベースの独立性に関する最も強力な議論は、データベース バックエンドに対する独自の好みを持つ企業にソフトウェアを販売できることです。
したがって、データベースからストアド プロシージャを削除することについての主な議論は、技術的なものではなく、商業的なものに過ぎないと考えています。技術的な理由があるかもしれませんが、そこに保持する技術的な理由もあります。たとえば、パフォーマンス、整合性、複数のアプリケーションが同じ API を使用できるようにする機能などです。
SP を使用するかどうかは、使用するデータベースにも大きく影響されます。データベースの独立性を考慮しないと、T-SQL または PL/SQL を使用した場合とはまったく異なる経験になるでしょう。
Oracle を使用してアプリケーションを開発している場合、PL/SQL は言語として当然の選択です。これはデータと非常に緊密に結合されており、リリースごとに継続的に改善されており、適切な開発ツールは PL/SQL 開発を CVS や Subversion などと統合します。
Oracle の Web ベースの Application Express 開発環境は、100% PL/SQL で構築されています。
データベースの独立性が必要な場合は、アプリケーション層で利用可能な標準がデータベース層で利用可能な標準よりもはるかに普及しているため、すべてのビジネスロジックをアプリケーション層に配置することをお勧めします。
ただし、データベースの独立性が最大の要因ではなく、チームのスキルセットに強力なデータベーススキルが含まれている場合は、ビジネスロジックをデータベースに配置することが最善の解決策になる可能性があります。アプリケーション担当者にアプリケーション固有のことを実行させ、データベース担当者にすべてのクエリが確実に実行されるようにすることができます。
もちろん、SQLステートメントをまとめることができることと「強力なデータベーススキル」を持つことには大きな違いがあります。チームが後者よりも前者に近い場合は、この世界の休止状態の1つを使用してロジックをアプリケーションに配置します。 (またはチームを変更してください!)。
私の経験では、エンタープライズ環境では、この領域に単一のターゲットデータベースとスキルがあります。この場合、データベースにできることはすべて入れてください。ソフトウェアを販売するビジネスをしている場合、データベースライセンスのコストはデータベースの独立性を最大の要因にし、アプリケーション層で可能なすべてを実装することになります。
お役に立てば幸いです。
最近では、ストアド プロシージャ コードを Subversion に送信し、適切なツール サポートを使用してこのコードをデバッグすることが可能です。
SQL ステートメントを組み合わせたストアド プロシージャを使用すると、アプリケーションとデータベース間のデータ トラフィックの量を減らし、データベース呼び出しの数を減らし、パフォーマンスを大幅に向上させることができます。
C# でのビルドを開始してから、ストアド プロシージャを使用しないことに決めましたが、現在はますます多くのコードをストアド プロシージャに移行しています。特にバッチ処理。
ただし、トリガーを使用しないでください。ストアド プロシージャまたはより優れたパッケージを使用してください。トリガーは保守性を低下させます。
コードをアプリケーション層に配置すると、DB に依存しないアプリケーションになります。
パフォーマンス上の理由から、ストアド プロシージャを使用した方がよい場合もあります。
それは(いつものように)アプリケーションの要件によって異なります。
データベースに入る唯一のものはデータです。
ストアド プロシージャはメンテナンスの悪夢です。それらはデータではなく、データベースに属していません。開発者と DBA の間の際限のない調整は、組織的な摩擦にすぎません。
ストアド プロシージャの適切なバージョン管理を維持するのは困難です。データベース外のコードのインストールは非常に簡単です。バージョンが間違っていると思われる場合は、SVN UP (おそらくインストール) を実行するだけで、アプリケーションは既知の状態に戻ります。環境変数、ディレクトリ リンク、およびアプリケーションに対する多くの環境制御があります。
簡単なPATH
操作で、さまざまな状況 (トレーニング、テスト、QA、生産、顧客固有の機能強化など) に使用できるバリアント ソフトウェアを用意できます。
ただし、データベース内のコードの管理ははるかに困難です。どのソフトウェアが使用されているかを制御するための適切な環境 (「PATH」、ディレクトリ リンク、またはその他の環境変数) はありません。データベースにスタックされ、データと結合された、永続的でグローバルにバインドされたアプリケーションソフトウェアのセットがあります。
トリガーはさらに悪いです。それらはメンテナンスとデバッグの両方の悪夢です。彼らがどのような問題を解決するのかわかりません。それらは、誰かが利用可能なクラス (または関数ライブラリ) を正しく使用することを気にすることができなかった、正しく設計されていないアプリケーションを回避する方法のようです。
パフォーマンスの議論に説得力があると考える人もいますが、私はストアド プロシージャがそれほど高速であると納得させるのに十分なベンチマーク データをまだ見ていません。誰もが逸話を持っていますが、アルゴリズムが多かれ少なかれ同じであるサイドバイサイドコードを持っている人は誰もいません。
[私が見た例では、古いアプリケーションは設計が不十分で混乱していました。ストアド プロシージャが作成されたときに、アプリケーションが再構築されました。プラットフォームの変更よりも、デザインの変更の方が影響が大きかったと思います。]
ビジネス ロジックは、最初の選択肢としてアプリケーション/中間層に配置する必要があります。そうすることで、ドメイン モデルの形式で表現したり、ソース管理に配置したり、分割したり、関連するコードと組み合わせたり (リファクタリング) したりできます。また、データベース ベンダーからの独立性も得られます。
また、オブジェクト指向言語は、ストアド プロシージャよりもはるかに表現力に優れているため、何が起こるべきかをコードでより適切かつ簡単に記述できます。
ストアド プロシージャにコードを配置する唯一の正当な理由は、そうすることが重要かつ必要なパフォーマンス上の利点を生み出す場合、または同じビジネス コードを複数のプラットフォーム (Java、C#、PHP) で実行する必要がある場合です。複数のプラットフォームを使用する場合でも、機能の共有により適した Web サービスなどの代替手段があります。
私の経験では、その答えは、通常、組織のスキルがどこにあるかによって決まるさまざまな価値観のどこかにあります。
DBMS は非常に強力な獣です。つまり、適切または不適切な処理は、大きな利益または大きな危険をもたらします。残念なことに、あまりにも多くの組織で、主な注意がプログラミング スタッフに向けられています。dbms スキル、特にクエリ開発スキル (管理とは対照的に) は無視されます。これは、dbms スキルを評価する機能もおそらく欠落しているという事実によって悪化しています。
そして、データベースについて理解していないことを十分に理解しているプログラマーはほとんどいません。
そのため、Active Records や LINQ などの次善の概念が人気を博しています (明らかなバイアスを投入するため)。しかし、それらはおそらくそのような組織にとって最良の答えです。
ただし、大規模な組織では、データストアの効果的な使用により多くの注意を払う傾向があることに注意してください。
私見では。リレーショナルデータベース駆動型アプリのどこにビジネスロジックを配置するかを決定することには、2つの相反する懸念があります。
再。保守性:効率的な将来の開発を可能にするために、ビジネスロジックは、デバッグとバージョン管理が最も簡単なアプリケーションの部分に属します。
再。信頼性:不整合の重大なリスクがある場合、ビジネスロジックはデータベース層に属します。リレーショナルデータベースは、データの制約をチェックするように設計できます。たとえば、特定の列にNULL値を許可しないなどです。アプリケーション設計で、一部のデータを複雑すぎてこれらの単純なものでは表現できない特定の状態にする必要があるシナリオが発生した場合制約がある場合は、データベース層でトリガーなどを使用するのが理にかなっています。
トリガーは、最新の状態に保つのが面倒です。特に、アプリがアクセスできないクライアントシステムで実行されることになっている場合はなおさらです。しかし、それはそれらを追跡したり更新したりすることが不可能であることを意味するものではありません。それは苦痛であり面倒であるという彼の答えのS.Lottの議論は完全に有効です、私はそれを2番目にし、そこにもいました。ただし、最初にデータレイヤーを設計するときにこれらの制限を念頭に置いて、管理可能な絶対的な必需品以外の目的でトリガーや関数を使用しないようにしてください。
私たちのアプリケーションでは、ほとんどのビジネスロジックはアプリケーションのモデルレイヤーに含まれています。たとえば、請求書は特定の販売注文から自分自身を初期化する方法を知っています。このような複雑な一連の変更のためにさまざまなものが順番に変更される場合、ストアドプロシージャを選択するのではなく、一貫性を維持するためにそれらをトランザクションにロールアップします。合計などの計算はすべてモデルレイヤーのメソッドを使用して行われます。ただし、パフォーマンスのために何かを非正規化する必要がある場合、またはすべてのクライアントがセッションキャッシュで期限切れにする必要があるオブジェクトを特定するために使用する「変更」テーブルにデータを挿入する必要がある場合は、データベースレイヤーのトリガー/関数を使用して新しい行を挿入しますこのトリガーから通知(Postgresリッスン/通知)を送信します。
私たちのアプリを約1年間フィールドに置いて、毎日何百人もの顧客が使用した後、ゼロから始める場合に変更するのは、データベース関数(またはストアドプロシージャ、ただし、最初からバージョン管理と更新を念頭に置いて、それらを呼び出したい)。
ありがたいことに、スキーマのバージョンを追跡するためのシステムがいくつか用意されているので、その上にデータベース関数の置き換えを処理するための何かを構築しました。ただし、最初から交換する必要があると考えていれば、時間を節約できたはずです。
もちろん、RDBMSの領域を超えて、Amazon SimpleDBやGoogleのBigTableなどのタプルストレージシステムに入ると、すべてが変わります。しかし、それは別の話です:)
Bussinessアプリケーションの「レイヤー」は次のとおりです。
これにより、ビジネスユーザーのh(is / er)ジョブのビューが実装されます。ユーザーがよく知っている用語を使用します。
ここで計算とデータ操作が行われます。データの変更を伴うビジネスロジックはすべてここに実装されます。
これは次のようになります。正規化されたシーケンシャルデータベース(標準のSQLベースのDBMS)。ビジネスデータをラップするオブジェクトを格納するオブジェクト指向データベース。等
上記のレイヤーに到達するには、必要な分析と設計を行う必要があります。これは、ビジネスロジックを最適に実装する場所を示します。データの整合性ルールとデータ更新に関する同時実行/リアルタイムの問題は、通常、計算フィールドと同様に、データのできるだけ近くに実装されます。これは適切な指針です。データの整合性とトランザクション制御が絶対に必要なストアドプロシージャ/トリガーへ。
データの意味と使用を含むビジネスルールは、ほとんどの場合、処理レイヤーに実装されますが、ユーザーのワークフローとしてユーザーインターフェイスにも表示されます。さまざまなプロセスを、ユーザーの仕事。
この質問に対する単独の正解はありません。アプリの要件、開発者の好みとスキル、月の満ち欠けによって異なります。
ビジネス ロジックは、データベースではなくアプリケーション層に配置する必要があります。その理由は、データベース ストアド プロシージャは、使用するデータベース製品に常に依存するためです。これにより、3 層モデルの利点の 1 つが失われます。このデータベース製品に追加のストアド プロシージャを提供しない限り、他のデータベースに簡単に変更することはできません。一方、パフォーマンスを最適化するためにロジックをストアド プロシージャに入れることが理にかなっている場合もあります。
私が言いたいのは、ビジネス ロジックはアプリケーション層に入れることですが、例外もあります (主にパフォーマンス上の理由)。
ストアド プロシージャには多くのビジネス ロジックが組み込まれています。これは理想的ではありませんが、多くの場合、パフォーマンスと信頼性のバランスが取れています。
そして、何エーカーものソリューションやコードベースを検索しなくても、それがどこにあるかがわかります!
スケーラビリティも、ビジネス ロジックをデータベース層よりも中間層またはアプリ層に適用するための非常に重要な要素です。
それは連続体です。私見最大の要因は速度です。保守性、パフォーマンス、スケーラビリティ、セキュリティ、信頼性などのプログラミングの優れたテナントに準拠しながら、この吸盤をできるだけ早く起動して実行するにはどうすればよいですか。多くの場合、SQL は何かを表現する最も簡潔な方法であり、たまたま文字列操作などを除いて、何度も最もパフォーマンスが高くなりますが、それはCLR Procsが役立つ場所です。私の信念は、目の前の事業に最適だと思われるところならどこにでも、ビジネス ロジックを自由に散りばめることです。SQL を見てうんざりしているアプリケーション開発者がたくさんいる場合は、アプリケーション ロジックを使用させてください。大規模なデータセットを使用して高パフォーマンスのアプリケーションを本当に作成したい場合は、できるだけ多くのロジックを DB に配置してください。あなたのDBAを解雇してください」開発者は、開発データベースに対して究極の自由を得ることができます。この仕事に唯一の答えや最適なツールはありません。あなたは複数のツールを持っているので、アプリケーションのすべてのレベルの専門家になると、正当な場合には適切で簡潔な表現力のある SQL を記述し、それ以外の場合はアプリケーション層を使用することに多くの時間を費やしていることがすぐにわかります。私にとって最終的には、コードの行数を減らすことが単純化につながります。わずか 2500 行のアプリ コードと 1000 行の SQL を含む SQL リッチ アプリケーションを、15500 行のアプリ コードと 2500 行の SQL を持つドメイン モデルに変換して、以前の SQL リッチ アプリが行っていたことを実現しました。コードの 6 倍の増加を「簡素化」として正当化できる場合は、すぐに先に進んでください。あなたは複数のツールを持っているので、アプリケーションのすべてのレベルの専門家になると、正当な場合には適切で簡潔な表現力のある SQL を記述し、それ以外の場合はアプリケーション層を使用することに多くの時間を費やしていることがすぐにわかります。私にとって最終的には、コードの行数を減らすことが単純化につながります。わずか 2500 行のアプリ コードと 1000 行の SQL を含む SQL リッチ アプリケーションを、15500 行のアプリ コードと 2500 行の SQL を持つドメイン モデルに変換して、以前の SQL リッチ アプリが行っていたことを実現しました。コードの 6 倍の増加を「簡素化」として正当化できる場合は、すぐに先に進んでください。あなたは複数のツールを持っているので、アプリケーションのすべてのレベルの専門家になると、正当な場合には適切で簡潔な表現力のある SQL を記述し、それ以外の場合はアプリケーション層を使用することに多くの時間を費やしていることがすぐにわかります。私にとって最終的には、コードの行数を減らすことが単純化につながります。わずか 2500 行のアプリ コードと 1000 行の SQL を含む SQL リッチ アプリケーションを、15500 行のアプリ コードと 2500 行の SQL を持つドメイン モデルに変換して、以前の SQL リッチ アプリが行っていたことを実現しました。コードの 6 倍の増加を「簡素化」として正当化できる場合は、すぐに先に進んでください。最終的には、コードの行数を減らすことが単純化につながります。わずか 2500 行のアプリ コードと 1000 行の SQL を含む SQL リッチ アプリケーションを、15500 行のアプリ コードと 2500 行の SQL を持つドメイン モデルに変換して、以前の SQL リッチ アプリが行っていたことを実現しました。コードの 6 倍の増加を「簡素化」として正当化できる場合は、すぐに先に進んでください。最終的には、コードの行数を減らすことが単純化につながります。わずか 2500 行のアプリ コードと 1000 行の SQL を含む SQL リッチ アプリケーションを、15500 行のアプリ コードと 2500 行の SQL を持つドメイン モデルに変換して、以前の SQL リッチ アプリが行っていたことを実現しました。コードの 6 倍の増加を「簡素化」として正当化できる場合は、すぐに先に進んでください。
どこかで記事を読んだことを覚えています。それは、すべてのことは、あるレベルではビジネス ロジックの一部である可能性があり、そのため、この質問は無意味であると指摘していました。
与えられた例は、画面上の請求書の表示だったと思います。期限切れのものを赤でマークする決定は、ビジネス上の決定です...
ビジネス ロジックは通常、オブジェクトと、カプセル化、継承、およびポリモーフィズムのさまざまな言語構造によって具体化されます。たとえば、銀行アプリケーションがお金をやり取りしている場合、「お金」のビジネス要素を定義する Money 型が存在する可能性があります。これは、プリミティブな 10 進数を使用してお金を表すのとは対照的です。このため、適切に設計された OOP は「ビジネス ロジック」が存在する場所であり、厳密にはどの層にもありません。