19

現在、データベース内のいくつかのテーブルの履歴テーブルを作成するというアイデアをいじっています。基本的に、メイン テーブルとそのテーブルのコピーがあり、変更日とアクション列があり、実行されたアクション (更新、削除、挿入など) を格納します。

これまでのところ、履歴テーブルの作業を行うことができる 3 つの異なる場所を考えることができます。

  • 更新、挿入、および削除のためのメイン テーブルでのトリガー。(データベース)
  • ストアド プロシージャ。(データベース)
  • アプリケーション層。(応用)

私の主な質問は次のとおりです。これらの各レイヤーで作業を行うことの長所、短所、落とし穴は何ですか?

トリガーを使用する利点の 1 つは、データベース上に何が実装されていても、整合性が常に維持されることです。

4

6 に答える 6

13

私はそれを次のように言います:

  • ストアド プロシージャ:テーブルを直接変更するとバイパスされます。データベースのセキュリティでこれを制御できます
  • 申し込み:同額。また、おそらく異なる言語で複数のアプリケーションがある場合は、各スタックに実装する必要がありますが、これは多少冗長です。と
  • トリガー:アプリケーションに対して透過的で、すべての変更をキャプチャします。これは私の好みの方法です。
于 2009-08-09T03:34:08.287 に答える
10

トリガーは、単純な履歴を作成するための最も迅速で簡単な方法です。次の情報は、履歴処理にいくつかのビジネス ルールが含まれる可能性があり、追跡対象のテーブルにないログ情報が必要になる可能性がある、より複雑な例を想定しています。

トリガーはバイパスできないため、sproc よりも安全であると考えている人には、次の仮定をしていることを思い出してください。

!) ユーザーが DISABLE TRIGGER を実行できないようにする許可が存在します [ただし、エンタープライズ アプリケーションの一般的なパターンである sprocs での EXECUTE を除いて、データベースへのすべてのアクセスを制限する許可も存在する可能性があります] - したがって、正しい許可を想定する必要があり、したがって sprocs は等しいと想定する必要があります。セキュリティとバイパス機能に関するトリガー

!) データベースによっては、トリガーを起動しない更新ステートメントを実行できる場合があります。ネストされたトリガーの実行深度に関する知識を利用して、トリガーをバイパスできます。唯一の確実なソリューションには、データベースのセキュリティと、承認されたメカニズムのみを使用してデータへのアクセスを制限することが含まれます。これは、トリガー、sproc、またはデータ アクセス レイヤーのいずれであってもかまいません。

ここでの選択は明確だと思います。データが複数のアプリケーションによってアクセスされている場合、最下位の共通レイヤーから履歴を制御する必要があり、これはデータベースを意味します。

上記のロジックに従うと、トリガーまたはストアド プロシージャの選択は、ストアド プロシージャが最下位の共通層であるかどうかによって決まります。パフォーマンスと副作用をより適切に制御でき、コードの保守が容易になるため、トリガーよりも sproc を優先する必要があります。

トリガーは許容されますが、更新中のテーブル以外のデータを読み取ってロックを増加させないようにしてください。トリガーをログ テーブルへの挿入に制限し、必要なものだけをログに記録します。

アプリケーションが共通の論理アクセス レイヤーを使用しており、これが時間の経過とともに変化する可能性が低い場合は、ここでロジックを実装することをお勧めします。Chain Of Responsibility パターンとプラグイン アーキテクチャを使用し、これを Dependency Injection から駆動して、履歴モジュールであらゆる種類の処理を可能にします。これには、まったく異なる種類のテクノロジ、異なるデータベース、履歴サービス、またはその他のあらゆるものへのログ記録が含まれます。想像できました。

于 2009-08-09T03:47:41.677 に答える
7

遅いものですが、考慮できるオプションがさらにいくつか追加されます。

変更データ キャプチャ: この機能は SQL Server 2008 R2+ で使用できますが、エンタープライズ エディションでのみ使用できます。追跡したいテーブルを選択すると、SQL Server がその仕事をしてくれます。トランザクション ログを読み取り、履歴テーブルにデータを入力することで機能します。

トランザクション ログの読み取り:データベースが完全復旧モードの場合、トランザクション ログを読み取ることができ、ほとんどのトランザクションの詳細を見つけることができます。

欠点は、これがデフォルトでサポートされていないことです。オプションは、 fn_dblog などの文書化されていない関数またはApexSQL Logなどのサードパーティ ツールを使用してトランザクション ログを読み取ることです。

トリガー:管理するトリガーが多すぎない少数のテーブルで問題なく機能します。監査したいテーブルがたくさんある場合は、サードパーティ製のツールを検討する必要があります。

これらはすべてデータベース レベルで機能し、アプリケーションに対して完全に透過的です。

于 2013-07-11T12:17:48.727 に答える
7

トリガーベースのアプローチを何年も使用しており、私たちにとっては間違いなくうまく機能していますが、次の点について熟考する必要があります。

  1. 頻繁に使用される (たとえば、マルチテナントの SaaS ベースのアプリケーション) でのトリガーは、非常に高価になる可能性があります。

  2. シナリオによっては、いくつかのフィールドが冗長になることがあります。トリガーは、ログに記録するフィールドがはっきりしている場合にのみ有効です。アプリケーションを使用すると、「構成」に基づいて特定のフィールドをログに記録するのに役立つインターセプターレイヤーを持つことができます。ただし、オーバーヘッドの独自のシェアがあります

  3. 適切なデータベース制御がなければ、トリガーを簡単に無効化し、データを変更し、トリガーを有効にすることができます。アラームを発生させることなくすべて

  4. 接続がプールから確立される Web アプリケーションの場合、変更を行った実際のユーザーを追跡するのは面倒な場合があります。考えられる解決策は、すべてのトランザクション テーブルに「EditedBy」フィールドを含めることです。

于 2011-01-31T10:46:44.867 に答える
2

トリガーは、変更をキャプチャする唯一の信頼できる方法です。Stored Procs またはアプリでそれを行うと、いつでも SQL を実行して、ログがない変更を (不注意で) 削除することができます。もちろん、ログを残したくない人はトリガーを無効にすることができます。しかし、ロギングを忘れずに含めることを期待するよりも、誰かにロギングを無効にするように強制したいでしょう。

于 2009-08-09T03:34:02.640 に答える
0

通常、アプリケーションレイヤーを選択した場合は、すべての履歴テーブルを一貫して処理する単一のポイントでロギングを実行するようにアプリコードを設計できます。異なるトリガーは、(dbテクノロジーに応じて)すべてのテーブルに複製されるため、維持するためのより複雑なアプローチです。数百のテーブルの場合、トリガーのコード量が問題になります。

あなたが今書いているコードを維持するサポート組織があり、誰があなたのコードを維持するかわからない場合(大企業に最適)、あなたのコードを修正する人のスキルレベルがどれであるかを推測することはできませんアプリケーションの場合、私の意見では、履歴テーブルの動作原理をできるだけ単純にする方が適切であり、アプリケーション層はおそらくこの目的に最適な場所です。

于 2011-05-29T09:00:45.153 に答える