web-dev-qa-db-ja.com

データベース:アプリケーションロジックはどこで実行する必要がありますか?

http://highscalability.com/blog/2010/11/9/facebook-uses-non-stored-procedures-to-update-social-graphs.html Facebookがロジックをどのように移行したかについて話します開発の容易さを向上させるために、データベースをアプリケーションに組み込みます(データベース全体ではなく、従業員全体のスケーリングが向上します)。

データベース内とアプリケーション内の両方のロジックを実行することのビジネス上および技術上のトレードオフを評価する調査/記事/ベンチマークはありますか?

具体的には、(データベースのパフォーマンスとビジネスの成長に応じた開発の容易さの両方の点で)何がより適切に拡張できるのかと思います。

シナリオ1(データベースのロジック)

  • データベース側でロジックを実行します。
  • データベース固有のSQL拡張機能を使用します。
  • ストアドプロシージャの使用。
  • 短いトランザクションでのクエリが少なく、ネットワークオーバーヘッドが少ない。

シナリオ2(アプリケーションのロジック)

  • アプリケーション側でロジックを実行します。
  • すべての主要なデータベースで共通の機能に制限されます。
  • ストアドプロシージャを使用しない。
  • 長いトランザクションに対する多くのクエリ、高いネットワークオーバーヘッド。

シナリオ1では、どのような人のスケーリングのオーバーヘッドが予想されますか?
シナリオ2では、どのようなデータベーススケーリングのオーバーヘッドが予想されますか?

17
Gili

私自身の質問への回答(これまでに読んだすべてを集約):

概要:一般的な考えに反して、パフォーマンスやセキュリティ上の理由からストアドプロシージャを使用しないでください。これらを使用してする必要があります複数のアプリケーションをサポートし、データの整合性を適用し、アプリケーション層で簡単に実装できない分野横断的な問題を実装します。

残りのすべてのロジックをアプリケーションレイヤーにプッシュしてください。

15
Gili

この選択を行う際の唯一の問題はスケーラビリティーではありません(私は何兆ものレコードを持つ成功したデータベースを知っているので、データベースは思ったよりスケーラブルです)。それはおそらく最も重要でもありません。

まず、データの意味を確認する必要があります。 Facebookのようなものは本質的にそのアプリケーションに関連付けられているため、ロジックを配置することは、インポート、データベースジョブ、複数の異なるアプリケーションからのユーザーデータエントリからデータを取得する必要があるビジネスアプリケーションほど危険ではありません。制御できません。したがって、データの整合性に対するリスクは、この選択を行う際に検討する必要がある最初かつ最も重要なことです。

また、データがどのように使用され、どの環境で重要であるか。情報はどのように監査されますか?規制要件はありますか?レポートはどのように行われますか?別のレポートシステムやユーザーアプリケーションでロジックを再利用できるようにする必要がありますか?もしそうなら、ロジックはアプリケーションの外で休む必要があります。データのエクスポートを実行する必要がありますか。それは、アプリケーション内のロジックによってどのように影響を受けますか。これは、レポートコードとエクスポートコードを記述しているユーザーが、アプリケーションコードにアクセスできないため、ロジックが何であるかを確認できないことを意味しますか?それは大きな問題になる可能性があります。

別の考慮事項は、パフォーマンスを含むスケーラビリティです。どのくらいの拡張性が必要ですか? Facebookのスケーラビリティを必要とするものはほとんどありません。どのくらいのパフォーマンスが必要ですか?必要のないスケーラビリティーを設計すると、最適な結果が得られません。アプリケーションにロジックを配置するために使用するメソッドは、データベースのパフォーマンスに悪影響を及ぼしますか(たとえば、多くのORMが恐ろしいデータベースコードを書き込みます)。

それから、ばかげている開発のためのより少ない時間についての議論があります。何をしているのかわかっている場合は、データベースにロジックを配置するのに、アプリケーションに配置するよりも時間がかかりません。ほとんどのアプリケーション開発者はSQLの専門家ではありません。しかし、SQLをより良くするために開発者の時間を節約することは本当にプラスですか?いいえ、その選択は、ほとんどの場合、データベースのパフォーマンスとデータの整合性を犠牲にして行われるためではありません。

私が言おうとしているのは、1つのサイズですべてに対応できるものはないということです。ロジックをアプリケーションに配置することが理にかなっているアプリケーションとそうでないアプリケーションがありますが、選択を行うときに考慮すべき重要な要素が1つまたは2つだけであると考えるのは、一般に誤りです。

4
HLGEM

さて、実用的な答えがあります、そしてこれがこれです。

質問のタイトルは「アプリケーションロジックはどこで実行する必要がありますか?」しかし、あなたがそれについて考えるならば、これは分離可能であるべきである2つのことを膨らませます:

  • アプリケーションロジックはどのようにすべきですかコード化
  • アプリケーションロジックはどこにあるべきですかrun

現在のデータベーステクノロジーの一般的に認識されていない大きな弱点の1つは、これらの質問のいずれかを選択すると、通常、もう一方の質問に強いられることです。

  • データベースでアプリケーションロジックを実行することを選択した場合、データベースの手続き言語(eeek、PL/SQL)を使用するか、サードパーティの言語のストアドプロシージャをサポートするのは非常に面倒です。
  • アプリケーションロジックを適切なプログラミング言語でコーディングすることを選択した場合、同じロジックのいくつかをデータベースで同様にコーディングしてコーディングしない限り、データ整合性の利点が失われます。

しかし、理想的には、すべてのアプリケーションロジックを一度で、選択した強力なプログラミング言語でコーディングし、ロジックをアプリケーションで実行するかどうかを指定できる必要がありますまたは、データベースは遅延バインドされた決定でなければなりません。アプリケーションをデプロイするときに選択するか、実行時と同じくらい遅くすることもできます。

実際、理想的には、ブラウザー、アプリケーションサーバー、データベースで同じロジックを同時に実行できるはずです。フォーム駆動型Webアプリケーションの検証ルールを考えてみてください。理想的には、3つの層すべてで検証ロジックを実行する必要があります。

  1. ブラウザーがフォームを誤って入力しているときにユーザーに非常に低いレイテンシーフィードバックを提供できるため、ブラウザーは検証ロジックを実行する必要があります。また、ユーザーが無効なフォームを送信できないようにすることで、下位層の負荷を軽減します。
  2. アプリケーションサーバーは検証ロジックを実行する必要があります。ブラウザーがそうすることを信頼できないためです。ハッカーはブラウザーのロジックをバイパスできます。また、無効なフォームをデータベースに送信する前にキャッチすることで、重要な共有リソースの負荷を軽減します。
  3. データベースは検証ロジックを実行する必要があります。データベースは、データの複数のユーザーに対してデータの整合性を適用する責任があるためです。

したがって、実際には、そのロジックを1回コーディングし、それを3つの場所すべてに適用するツールを用意する必要があります。しかし、これを実現するための貴重な技術はほとんどありません。

2
sacundim

私はお勧め/好む傾向があります:

  • ロギング

    • アプリケーションロジックのアプリレベル(「ユーザーの削除」、「パスワードの変更」、「顧客の追加」)。
    • コンプライアンス/監査の場合、データベースに直接適用します(これにより、DBAなどの他の間接的なアクセス手段がキャッチされます)
  • セキュリティ/権限

    • セキュリティはアプリケーション内に実装する必要があります。
    • DBRMS内では、セキュリティをさまざまな方法で実装できます(SQL管理者、多くの場合ローカル管理者はSQL管理者である必要があります)、DB所有者、DBロール、オブジェクト権限です...これは混乱を招きやすい( " Xの権利を持っているのは誰ですか?」、「Jane DoeはどのようにしてYへのアクセス権を持っているのですか?」)...可能な限り避けてください。また、データベースに直接アクセスするためのツール(Excel、Accessなど)が非常に多いため、DBへの直接のアクセス権は危険な場合があります...ユーザーがDBに直接アクセスして、アプリのプロセスを迂回することはできません。
    • それに直面しよう、ほとんどのアプリは統合認証(NTLM/Kerberos)を使用しません。 WebAppはKerberosを必要としますが、これは多くの人にとって迷惑で混乱を招きます。さらに、DB内の権限がアプリに問題を引き起こす可能性があることを意味します(たとえば、ユーザーが特定の呼び出しに失敗したために特定の呼び出しが失敗したときに、アプリが処理方法を知らない場合適切なグループに属している)...加えて、SQLに直接権限を適用して整合性を確保する方法が多すぎます...加えて、アプリはこのような誤った構成についてDBをスキャンしません( "gee、user can彼らはSAなので、実際にこのDBロールのメンバーになるべきです」)。
    • (MSSQL)アプリケーションロールはめったに使用されませんが、(ここの開発者を見て)する必要があります。 SQL内でアプリの権限を適用する優れた方法。
  • クエリ

    • 単純なクエリ(SELECT *、IDによるSELECT)は、動的SQLを作成するORMで処理できます。
    • 複雑なクエリは手作業で作成する傾向があるため、ORM内にsprocとマップを作成します
  • INS/UPD/DEL

    • 特に設定はありません。
    • 一方で、アプリオブジェクトをsprocに渡すと、テーブル間のINS/UPDトランザクションが簡単になります
    • 一方、スケールアウトは、一部のテーブルが他のサーバーに移動されることを意味する場合があるため、トランザクションは単一のサーバーに含まれません
    • また、トランザクションロックは、ロックがパフォーマンスの障害にならないように調整する必要があります。代替の「NOSQL」/「結果整合性」モデルは高パフォーマンスですが、より多くのコードとより多くのシステム管理者の労力を伴います(通常、データベース/キャッシュサーバー間のデータの追跡と伝達に関与するシステムが増えるため)。
  • SDL

    • 展開時にのみ実行する必要があります...おそらくインストール/アップグレードプロセスがSDLコードを実行します
1
Scott Brickey