データベースレイヤーにアプリケーションロジックを配置することに対する、またはそれに対する議論は何ですか?


74

Programmers.seとdba.seの対象者は異なり、異なる視点を持つため、この場合、データベースレイヤーにアプリケーションロジックを配置したり、配置したりするための議論は何ですか?Programmers.seで。

これに関するdbaについての議論はすでに見つかりませんでした。元の投稿にはそれがすべて記載されています。

ほとんどのソフトウェア開発者は、アプリケーションロジックをアプリケーションレイヤーに保持することを望んでおり、おそらくここに保持するのが自然であると感じるでしょう。データベース開発者は、トリガーおよびストアドプロシージャとして、アプリケーションロジックをデータベース層に配置したいと考えているようです。

個人的には、アプリケーション層にできるだけ多くの層を残して、層のデバッグを容易にし、層の責任を分離しておくことを好みます。

これについてどう思われますか。また、データベースレイヤーに実装しても問題ない、またはすべきでないものは何ですか?

NB私はその質問のOPではありませんが、元の文言はそのまま残しました。


4
こことSOの回答を比較すると、ギャップは顕著です。開発者は、データベースでプロセスを集中化することに伴う遅れに抗議しますが、DBAには良いことです。 新しいビューまたはsprocの要求により多くの時間と労力をかけることを強制すると、データとの接点の数が減り、一貫性を維持しやすくなり、最適化の点の数が減ります。
すべての取引のジョン

ここでの答えは、データベースを使用する特定の方法(複数のアプリケーション、一部のユーザーが直接データベースにアクセスできるようにするなど)を想定しているように思えます。それが違いの主な理由だと思います。
JMD合体

回答:


56

さまざまな考え...

データベースコードは、アプリケーションクライアントテクノロジーよりも長持ちします。ADO.NET-> Linq-> EFおよび各種ORMを考えてください。一方、上記のすべてのクライアントテクノロジーに対して、過去年のSQL Server 2000コードを実行できます。

また、複数のクライアントの問題もあります。.net、java、Excelがあります。これが3セットのアプリケーションロジックです。

「ビジネスロジック」と「データ整合性ロジック」を混同しないでください。トランザクションを開始し、さまざまなチェックを行うクライアントがある場合、それは多くのdb呼び出しと長いトランザクションです。

アプリケーションロジックは、大量のデータには対応していません。ストアドプロシージャを使用して、1秒あたり5万行があります。Hibernateを使用する姉妹チームは、1秒間に1つを取得できません


リレーショナルデータベースを使用している限り
JMD Coalesce

1
@JMDCoalesce:あなたはまだビジネスロジックを必要としており、複数のクライアントアプリを持っている可能性があります。
gbn

40

データベース内のすべてのユーザーとすべてのアプリケーションに適用する必要があるすべてのロジックが必要です。それはそれを置く唯一の健全な場所です。

私が働いた最後のフォーチュン500には、少なくとも25の言語で記述されたアプリケーションがOLTPデータベースにアクセスしていました。これらのプログラムの一部は、1970年代に生産に移行しました。

この種の要件をデータベースに実装する代わりに、すべてのアプリケーションプログラマーがエディターを起動するたびに、最初にドアを通り抜けてから会社がなくなるまで、すべてまたは一部を100%正しく再実装できるようにすることです。ビジネス。

オッズは何ですか?

これは地球上で唯一の最大の「自分を繰り返さない」ではありませんか?


複数のアプリケーション1つのデータベースを使用する場合にのみ適用されます
JMD合体

1
多くの環境で一般的な@JMDCoalesce。メインアプリ、Excelレポート、サーバー側レポート、一括抽出:すぐに追加されます。ほとんどすべての銀行アプリケーションには、無数のクライアントアプリがあります。
gbn

もちろん、すべてのアプリケーションが銀行向けではありません。
JMD合体

29

回答はサイト間でかなり二極化されているように見えるので、古い回答をプログラマーから編集せずに移動しています。

私はここで怪我の世界にいることを知っていますが、データベースにビジネスロジックを入れます:

  • ビジネスパワーユーザーにデータベースへの直接アクセスを許可し、ユーザーがそれを台無しにすることを心配する必要はありません(または、アプリベースのロジックを使用する場合よりも心配する必要はありません)
  • パワーユーザーは、新しいソフトウェアリリースを待たずに新しいレポートを作成できます。
  • アプリベースのロジックをテストするのと同じように、データベースのコピーでSP / TRIGGERコードをテストできます
  • SQLを保持して、テキストファイルにspとトリガーを作成することができます(とにかくこれをテーブル/ビューコードに対して行う必要があります)
  • ビジネスロジックを移植せずに言語を組み合わせて一致させることができます
  • すべてのソフトウェアをアップグレードすることなく、ビジネスロジックを変更できます。
  • データベースのアクティビティを監査するのと同じ方法で、ロギングを介して構造の変更を監査します
  • 大幅に改善されたセキュリティときめ細かいアクセス制御(ほとんどのアプリベースのロジック実装は独自のセキュリティモデルを使用しているため、データの侵害がはるかに容易です。可逆パスワード暗号化は珍しくありません)
  • データベース側のユーザーセキュリティにより、SQLが実行できる損害/盗難を大幅に削減

短所は次のとおりです。-ユーザーがカスタムレポートの開発者に依存しなくなると、開発者は脅迫されます-開発者は別のプログラミング言語を学ぶ必要があります

どちらも熟練した開発者にとって重要ではありません。

興味深いことに、ほとんどの答えは、ビジネス機能を提供するソフトウェアが存在しないかのように、「ビジネスロジック」ではなく「アプリケーションロジック」の観点から語っています。


1
*ストアドプロシージャ/トリガーは、すべてのアプリケーションコードを変更せずにデータベースの構造を変更できるレベルの抽象化を提供できます。*データベースのすべてのユーザーがミドルウェアを忠実に使用するとは限りません。*さあ、外部キービジネスルールです!! *データベースからすべてのチェック/制約/コードを削除すると、不整合/破損から自身を保護できないことを意味します。*すべてのアプリは、eBay が成功し、それを構築する余裕があったに開発しような、キュー駆動のトランザクションレスデザイン必要としません。* SQLはそれほど難しくありません。
クレイグ14

23

最も重要な問題は、データベースの上の「レイヤー」がデータを所有していると考えているかどうかです。同時実行性とデータの整合性は、ソリューションがRDBMSである問題です。一部のアプリケーションは、データベースが単なる個人のビットバケットであるかのように開発され、もちろん、あらゆる種類の方法で車輪を再発明しようとするだけでなく、他のアプリケーションが同じデータベースにアクセスするとすぐに修復不能な破損


1
システムを後援する人は誰でもデータを所有していると思う-彼らはそれを支払った。また、データベースにヒットする前に多くの並行性の問題を解決します-多くの場合、はるかに簡単です。
AK

4
私とは異なる意味で「自分」を使用しています:私のポイントは、データベースにヒットする前に並行性の問題を「解決」する場合、データベースにヒットする唯一のアプリケーションまたは解決する必要があることも確認する必要があることですそのレベルでもう一度。「あなたのデータベースコードは、おそらくあなたのアプリケーションクライアントテクノロジーよりも長生きするでしょう。」
ジャックダグラス

17

これに対する答えをブログに書きました。私の結論は、アプリケーションのライフサイクル全体を考慮すると、アプリケーションでそれを行うことはスケールアップしないということです。


3. 基になるデータベースに整合性/チェック制約を追加し、データベースのストアドプロシージャ言語で実装されたより複雑なコードを使用します。これにより、1つの中心的な場所を維持することができ、知らないアプリケーションでもルールを完全に施行できます!言語の変更はデータベースよりもはるかに頻繁に変更されるため、アプリケーションポートフォリオ全体とライフサイクル全体でビジネスルールを表現する1つの言語を取得します。そして、最も重要なアプリケーションと同じくらいミッションクリティカルなシステム上で実行されます。エラーは、これらのアプリケーションのデータベースエラーを処理する既存のコードによって処理されます。もちろん、アプリケーションが破損する可能性がありますが、3つのシナリオのうち、これは最も少なく、破損したアプリケーションのみが変更を必要とします。すべてではありません(また、ほとんどのSP /データベースメカニズムでは、本当に必要な場合に1つのアプリケーションに対して例外を作成できます)。これはあなたのグリーンフィールドのサイトや小さな会社では問題ないと思いますか?あなたのビジネスが成功すれば、30年後にはあなたが私の知恵に注意を払ったことを望むでしょう!

…いくつかの[異議]よく耳にする:

  • DBに展開されたSPコードのバージョン管理は困難です。アプリサーバーにデプロイされたJavaコードをバージョン管理するのは難しいと言うよりも、それは真実ではないと思います。つまり、それはまったく難しくなく、当たり前のことです。また、Rubyランドでは、開発環境から本番環境にコードを移行する方法についての本全体が書かれており、他の言語コミュニティが苦労しているようには見えません。それでも、ストアドプロシージャをバージョン管理することは明らかに困難です。
  • ストアドプロシージャはテストが困難です。これは奇妙なものです。まず、SPは厳密に入力されます。コンパイラは、意味のないコードパスがあるかどうかを通知し、少なくともOracleでは、すべての依存関係を計算します。それで、Rubyで必要になるかもしれない一般的な単体テストのセットが、すぐに排除されます。OOコードをテストするには、モックを作成して、テストシナリオを表すのに必要な内部状態にオブジェクトを強制する必要があります。テストデータの設定はどのように異なりますか?PL / SQLおよびその他のツール用のTAPプロデューサーがあります。デバッガーとプロファイラーもあります。
  • ストアドプロシージャ言語は、完全な機能を備えた言語ではありません。さて、ストアドプロシージャだけでアプリケーション全体を記述しようとしているのではありません。ほとんどの専用SP言語には、予想されるすべての最新の構成要素があり、少なくともOracleでは、オブジェクト指向開発者が使い慣れているすべての言語機能または任意の言語の外部プロシージャでJavaストアドプロシージャを使用できます。重要なのは、ロジックが実装されている場所(データに近い1か所)であり、実際の言語は単なる詳細です。PL / SQLはネイティブコードにコンパイルされ、データベースとインプロセスで実行されます。それより高性能なアーキテクチャはありません。
  • 別の言語を学ぶ必要はありません。ちょっと見渡せば、これはどのデベロッパーにとっても大きな赤旗です(特に、とにかく他の言語のプロダクションアプリを変更することを提案するものです!)現代の環境で働くことを学ぶことはたくさんあります:典型的なJavaショップにはEclipseがあります、WebLogic、Maven、Hudson、Anthill、Subversion、その他多数のアプリケーションコードを1行記述する前に学習する必要があります。非常に高いレベルのSP言語の実用的な知識は、比較すると簡単です。おそらく、専門家やDBAがあなたを助けてくれるでしょう。開発者のお気に入りのHibernateには独自のクエリ言語が付属していることは言うまでもありません…


12

SQLは、セットロジックやアプリケーション指向の結果フィルタリングなどを行いますか?SQLは素晴らしいセット操作言語です。

さらに、GBNが上記について指摘したように、SQLコードはほぼ普遍的にアプリケーションコードよりも長持ちします。

EF、NHibernate、LinqToSqlなど、コードをより高速に生成できるものは間違いありませんが、パフォーマンスに値するプログラマーなら誰でも、SQLの最適化のみがデータ取得を最適化することを知っています。RDBMSはSQLのみを理解するため、すべてのことを言って実行する前に、すべてをSQLにする必要があります。(TSQLとPLSQLがまだSQLであることに同意できると仮定)


11

人々が必ずしも議論しているわけではない1つの欠点-ここで長所が尽きている-はコストです。

データベースサーバーのCPUは、ソフトウェアライセンスの費用を負担する場合、組織内で最も高価なCPUであることがよくあります。そのため、ビジネスロジックをデータ層に移動することは、必ずしも均一に行う必要はなく、慎重に行う必要があります。


7

ここで、頭脳、つまり開発者(DV)とDBAの頭脳の出会いが必然的に起こるはずです。ビジネスロジック(BL)を使用してデータベースに保存すると、その実装を美化または恐怖に陥れる可能性があります。

一部のRDBMS製品には、ビジネスロジックとオブジェクトインフラストラクチャ用の優れたライブラリ/ツール/ APIがあり、それらをアプリケーションですばやく学習して使用できます。他のRDBMSの場合、ライブラリ/ツール/ APIは存在しません。

これまで、クライアントサーバーアプリはストアドプロシージャ(SP)を介してBLへのブリッジを作成していました。OracleやSQL Serverなどの製品の場合、これは早期に行われました。PostgreSQLやMySQLなどのオープンソースデータベースが登場すると、それらを使用するデータベースはBLのストアドプロシージャで新境地を開く危険性がありました。PostgreSQLは、ストアドプロシージャが実装されただけでなく、顧客の言語を作成する機能も登場したため、この点で非常に急速に成熟しました。MySQLは、基本的にストアドプロシージャの世界での進化を止め、多くの制限のある単純な形式の言語になりました。したがって、BLに関しては、MySQLとそのストアドプロシージャ言語に完全に依存しています。

質問が1つだけ残っています。RDBMSに関係なく、BLの全体または一部をデータベースに常駐させる必要がありますか?

開発者のことを考えてください。アプリケーションで問題が発生した場合、デバッグプロセスでは、断続的に正しい場合とそうでない場合があるデータチャネジャーを追跡するために、開発者がデータベースに出入りします。これは、C ++アプリケーションをコーディングし、途中でアセンブラーコードを呼び出すようなものです。ソースコード、クラス、構造体から割り込み、レジスター、オフセットに切り替えて、戻る必要があります!!! これにより、デバッグが同じレベルになります。

開発者は、データベースではなくメモリ内にあるビジネスオブジェクトを介して、言語構成(C ++のコンパイラフラグ、PHP / Pythonの異なる設定など)とともにBLを高速実行する方法を作成できる場合があります。一部の人は、データベースにストアドプロシージャとトリガーのデバッグがうまく統合され、見かけ上使用できないライブラリを作成することにより、データベースへのコードの実行を高速化するためにこのイデオロギーを橋渡ししようとしました。

したがって、開発者は、2つの言語でソースコードとBLを開発、デバッグ、および保守することが求められます。

次に、DBAについて考えます。DBAは、データベースを無駄のない状態に保ち、ストアドプロシージャの領域で可能な限り意味を持ちたいと考えています。DBAはBLをデータベースの外部にあるものと見なす場合があります。それでも、SQLがBLに必要なデータを要求する場合、SQLは無駄のない、平均的なものである必要があります。

今、心の出会いのために!!!

開発者はSPをコーディングし、反復メソッドを使用します。DBAはSPを調べます。DBAは、開発者が作成した反復メソッドを単一のSQLステートメントで置き換えることができると判断します。開発者は、DBAによって提案されたSQLステートメントが、SQLステートメントの通常の実行計画に従わない他のBL関連コードまたはSQLの呼び出しを必要とすることに気付きます。

これに照らして、構成、パフォーマンスチューニング、およびSPコーディングは、データ検索のためのBLの深さとデータ集約度の関数になります。BLの深さとデータ集約度が高いほど、開発者とDBAは、データベースに与えられるデータ量と処理能力のために同じページにいる必要があります。

結論

データ取得の方法は、常に開発者キャンプとDBAキャンプの両方を含む必要があります。速度と効率の両方のために、どのコーディング方法とデータ検索パラダイムが連携して機能するかに関して、常に譲歩しなければなりません。ソースコードが処理するデータの準備がコードがデータを取得する前に1回だけ行われる場合、DBAはリーンSQLと平均SQLの使用を指示する必要があります。BLがDBAが調整していないものである場合、手綱は開発者の手にあります。これが、DBAが自分自身やプロジェクトチームの一員であり、自分自身の島ではなく、開発者がDBAにSQLの微調整を許可する必要がある場合に、そのことを見なければならない理由です。


4

DBAでいっぱいのWebサイトで質問するのはいい質問です。うまくいけば、答えのほとんどがデータベースをACID状態に保ち、ビジネスロジックをデータベースに保持することに「賛成」になることを願っています。:-)

私の意見としては、アプリケーションとデータベースの両方にビジネスロジックを実装する必要があると思います。このアプローチはより多くの時間とお金がかかりますが、結果として質的に優れたビジネスソリューションになると思います。


1
2つのレイヤーで同じロジックですか?
dezso

新しい顧客を作成する場合、その顧客の名前と顧客番号(常に4つの数字が含まれる)を保存する必要がある場合、SQLステートメントを送信する前に、顧客番号が有効かどうかをアプリケーションで確認したいデータベース(ステートメントがデータベース内のビジネスロジックを渡さないことを知っている)。
ルードヴァンデビーテン

2
すべてのビジネスロジックはデータベースに実装する必要があります(「ロジック」を分割しないでください)。アプリケーションで簡単にチェックできるもの(Javascriptの正規表現など)はすべて、データベースでの作業が少なくなります(入力が無効な場合)。
ルードヴァンデビーテン

2
+1これは私がしていることです。私は単に「データベースにビジネスログインを入力し、アプリに利便性チェックを入れます」と呼びます
ジャックダグラス

1
この作業を行うには、体系的なアプローチが必要です。データを常に期待に一致させるコア整合性ロジックは、最初にデータベースで実行する必要があります。例外条件のデータベースからアプリとの良好なコミュニケーションを維持し、クライアントがそれらをユーザーに適切に伝えることができるようになるのは、次に来る。データベースにアクセスする前にそれらを予測することが最も重複する部分であり、必然的に同期を維持する必要があります。これらの同期を維持する必要性を最小限に抑えることができれば、最適です。
ケイドRouxの

2

Adam Muschが上で述べたように、パフォーマンスのためにここでさらに考慮すべきことがあります。CPU使用率。メモリ使用量。

明らかに間違ったものがデータベースに到達するのをブロックします。

  • 基本的な方法に準拠していないメールアドレスを除外します。
  • 長さを確認する

深くなるとき、それは決定を下す必要があるときです。DBサーバーは、クライアントが簡単にできることを行うための非常に高価な場所です。例:データの書式設定、日付の書式設定、文字列の組み立てなど、クライアント側。

クライアントまたはDBサーバーで計算/処理を行いますか?私にとっては、複雑さと関係するレコードの数に依存します。すべてが同じように扱われるように、ビジネスロジックは実際にDB自体で実行する必要があります。
将来的に頭痛の種を省くために、DBにデータを書き込むために、procsを読み込んで格納するビューのAPIを実際に作成する必要があります。

あなたの利益に各端の強みを使用してください。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.