35

監査が必要なテーブルごとにトリガーと個別の履歴テーブルを使用して、データベースに単純な監査証跡を導入することを計画しています。

たとえば、StudentScore テーブルを考えてみましょう。これには、対応する親テーブル (Student & Course) にリンクする外部キー (StudentID、CourseID など) がほとんどありません。

Table StudentScore (
    StudentScoreID, -- PK
    StudentID ref Student(StudentID),  -- FK to Student
    CourseID ref Course(CourseID),   -- FK to Course
)

StudentScore に監査が必要な場合は、監査テーブル StudentScoreHistory を作成する予定です -

Table StudentScoreHistory (
    StudentScoreHistoryID, -- PK
    StudentScoreID,
    StudentID,
    CourseID,
    AuditActionCode,
    AuditDateTime,
    AuditActionUserID
)

StudentScore のいずれかの行が変更された場合、古い行を StudentScoreHistory に移動します。

設計に関する議論で提起されたポイントの 1 つは、参照整合性を維持するために、StudentHistory テーブルの StudentID と CourseID を FK にすることでした。これを支持する議論は、ほとんどの場合、ハード削除ではなくソフト (論理ブール値フラグ) 削除を行うためであり、参照整合性を維持して、監査テーブルに孤立した ID がないことを確認するのに適しています。

Table StudentScoreHistory (
    StudentScoreHistoryID, -- PK
    StudentScoreID,
    StudentID ref Student(StudentID), -- FK to Student
    CourseID ref Course(CourseID), -- FK to Course
    AuditActionCode,
    AuditDateTime,
    AuditActionUserID
)

これは私には少し変わったデザインのようです。監査記録が親データの削除を停止してはならないという@Jonathan Leffler のコメントに同意します。代わりに、これが必要な場合は、監査テーブルではなく、メイン テーブルの外部キーを介して処理する必要があります。外部キーを監査テーブルに拡張する際に何らかの価値が失われていないことを確認するために、意見を求めたいと思います。

ここで私の質問は次のとおりです。 これらの外部キーを履歴テーブルに入れるのは良い設計ですか?

重要な議論 (ex パフォーマンス、ベスト プラクティス、設計の柔軟性など) の詳細を教えていただければ幸いです。

特定の目的と私たちの環境を探している人の利益のために:

目的:

  1. 重要なデータ履歴を維持する
  2. シナリオの再作成をサポートするユーザー アクティビティの監査を許可する
  3. 限られた範囲でユーザー アクティビティのロールバックを許可する

環境:

  • トランザクション データベース
  • すべてのテーブルで監査が必要なわけではありません
  • 特に静的/参照データに対して、可能な範囲で論理的な削除を使用します
  • 非常にトランザクションの多いテーブルで、物理的な削除を使用するものはほとんどありません
4

9 に答える 9

30

監査について話し合うとき、私はその背後にある目的に戻ります。これは実際にはバックアップではなく、過去の履歴です。たとえば、のStudentScore場合、生徒が元々65%であったのに、現在は95%であるという事実を失わないようにする必要があります。この監査証跡を使用すると、変更をさかのぼって、何が起こったのか、誰が行ったのかを確認できます。これから、特定のユーザーがシステムを悪用するために何をしたかを特定できます。テーブル全体をロールバックせずにこれらの変更を以前の状態にロールバックできるため、ある意味でこれは一種のバックアップになる可能性があります。

これを念頭に置いて(これを何に使用するかについての私の仮定が正しい場合)、FK / PK関係が必要になる唯一の場所は、履歴テーブルとその「ライブ」対応物の間です。監査(履歴)テーブルは、そのシステムの一部ではなくなったため、他のテーブルを参照しないでください。代わりに、それは単に1つのテーブルで起こったことの記録です。限目。考慮したい唯一の参照整合性は、履歴テーブルとライブテーブルの間です(したがって、FK / PKの関係の可能性があります)。ライブテーブルからのレコードの削除を許可する場合は、履歴テーブルにFKを含めないでください。次に、履歴テーブルに削除されたレコードを含めることができます(これは、削除を許可する場合に必要なものです)。

この履歴テーブルを使用したメインデータベースのリレーショナル整合性と混同しないでください。履歴テーブルはすべてスタンドアロンです。これらは、1つのテーブルの履歴としてのみ機能します(テーブルのセットとしては機能しません)。

2つの履歴テーブルを関連付けることが可能であり、ライブテーブルと履歴テーブルをさらに高度に関連付けることができるため(たとえば、ライブと履歴の両方を含む学生とコース)、学生が削除された可能性にも対処できます(震え)レコードはまだ履歴テーブルにあるためです。ここでの唯一の問題は、特定のテーブルの履歴を保持しない場合です。この場合、そのデータを失うことを選択します(削除を許可する場合)。

于 2011-05-14T04:38:05.973 に答える
6

シナリオを再作成する必要がある場合は、はい、FKが必要だと思います。FKを持っていると、関連する関連する詳細レコードを追跡するのが簡単になると思います。ただし、これにより、削除が問題になるだけでなく、主キーテーブルで変更される可能性のある情報も問題になります。この場合、他のテーブルにFKがあるレコードを削除するのではなく、すでに示したようにソフト削除を使用ます。

PKテーブルの情報が変更される限り、エンプターに注意してください。FKを設定することは、トレースバック機能を取得するための簡単な方法ですが完全ではありません。トレードオフがあります。完全な履歴を取得するには、基本的に、監査候補レコードに何かが発生した場合は常に、関連するすべてのレコードのバックアップコピーを作成する必要があります。イベントの完全な記録は設定が複雑になり、その過程で多くのスペースを消費する可能性があるため、適切な粒度のレベルを把握してそれに合わせる必要があります。

また、これはオプションである場合とそうでない場合がありますが、自社開発の監査ソリューションではなく、 ApexSQL監査+ ApexSQLログなどのツールの組み合わせを強く検討します。ニーズに基づいて、トランザクションログを定期的にアーカイブすることと組み合わせたこれらの2つのツールは、実行する必要があることをカバーします。監査ツールは同じデータベースまたは別の場所にデータを保存でき、ログツールはデータを選択的に回復できます。ちょっとした考え。

于 2011-05-17T18:17:16.923 に答える
6

外部キーを監査テーブルに拡張しないことをお勧めします。私の推奨事項は、監査のデータを外部キーの値まで拡張することです。

CourseID を「1」として格納する代わりに、「HTML4」になります。そうすれば、外部キーの値が削除されても、監査テーブルは引き続き有効です。これは、将来、外部キーの値が「HTML4」から「HTML5」に変更された場合にも当てはまります。外部キーのみを保存した場合、以前の受講生が「HTML5」を使用したと監査人に伝えることになり、これは正しくありません。

もう 1 つの大きな利点は、問題なくデータ マイニングのために監査証跡を別のサーバーに送信できることです。

上記のセットアップをしばらく使用しましたが、うまくいきます。

于 2011-05-16T12:00:28.433 に答える
4

あなたの走行距離は明らかに状況によって異なりますが、私の経験では、元のテーブルの主キーとの参照整合性を維持してください。これにより、関連するテーブルとの流動的な相互作用を可能にしながら、履歴の孤立した ID を回避できます。

たとえば、次のようなものがあるとします。

table scores (
 score_id,
 student_id ref students (student_id),
 course_id ref courses (course_id),
 score_date,
 score,
 pkey (score_id)
)

その場合、score_logs でスコア (score_id) を参照する on delete カスケード fkey を持つことは理にかなっています。それはオブジェクトです。ハード削除された場合は、履歴も破棄することをお勧めします。

対照的に、student_id と course_id の外部キーは、私の経験ではあまり意味がありません。それらは、学生とコースを参照するライブ行が存在しない場合でも、学生とコースを (ハード) 削除できないことを意味します。これは達成したいことかもしれませんが、その場合はヒントを無視してください。私の場合、ユーザー、コメント、製品、注文などを整理する必要があることに気づきました。履歴ログの外部キーにより、これが不便になります。

また、fkeys が不利に働く場合があることに注意してください。注文に注文明細があり、その注文明細が削除された場合でも、その注文明細の履歴が必要です。この場合に使用する正しい pkey は、order_line_id ではなく、order_id です。

最後に、fkeys を保持することを選択した場合に備えて、fkeys が何を指す必要があるかを検討してください。分離されたデータ (学生とコースなど) では、実際の行は問題ないと想定するのが妥当です。ただし、強く結合されたデータ (製品やプロモーションなど) では、本当に必要なのは fkey とそのバージョンの両方を参照することです。

前の 2 つの点に関して、この関連するスレッドと回答が興味深いと思うかもしれません。

集約ルートの監査証跡をどのように作成しますか?

于 2011-05-14T14:08:49.437 に答える
3

システムが本当にトランザクション処理に重点を置いている場合、私の答えは当てはまらないかもしれませんが、データ ウェアハウス/BI の世界では、この問題は「スター スキーマ」を使用することで解決されることがよくあります。このアプローチでは、リンクされたテーブルからの重要な指示情報を監査レコードと共に非正規化します。これには、親テーブルの PK 値 (つまり、監査対象テーブルの FK 値) が含まれる場合があります。ただし、実際の参照整合性制約自体は保持されません。

したがって、あなたの例では、StudentScoreHistory テーブルは、FK 制約なしで StudentID 列を保持できます。また、StudentName (または Student から必要と思われるもの) も保持できます。このようにして、監査証跡に戻って、親レコードのハード削除かソフト削除かを気にすることなく、何がいつ起こったかをまとめることができます。これには、子レコードが最初に記録されたときと同じように、変更可能な親テーブルの属性を追跡するという利点 (または見方によっては欠点) があります。たとえば、学生 123456 は、現在 Marriedlady 夫人であり、生物学の学位を授与されたときは Miss Singlegirl でした。

于 2011-04-27T01:04:29.023 に答える
3

ライブ スキーマはリレーショナル整合性を強制するため、履歴スキーマに外部キーは必要ありません。別の言い方をすれば、History スキーマのテーブル間に外部キーを適用する唯一の理由は、ライブ スキーマの変更からデータを入力する以外に、History スキーマに対して DML を実行する何らかのメカニズムがある場合です。その場合、履歴スキーマは監査証跡としてはほとんど役に立ちません。

問題を混乱させる論理的な削除の問題を提起します。StudentScoreHistoryこれは、参照など、2 つのスキーマ間に外部キーを持つことを検討している場合にのみ関連しますStudentScore。これは有効な設計である可能性がありますが、繰り返しますが、監査メカニズムを信頼していないことを示唆しています。個人的には、ライブ テーブルで物理的な削除を行い、削除の事実を履歴テーブルに記録することを好みます。ソフト削除は、悲しみの別の原因です。

しかし、とにかくこれは別の質問です。各テーブルのライブ バージョンと履歴バージョンの間に外部キーを持つことは完全に可能StudentScoreHistory -> StudentScoreですStudentScoreHistory -> StudentHistory

于 2011-04-27T06:31:02.737 に答える
2

非常によく似た監査システムを初めて実装している最中なので、現在、同じ懸念に直面しています。私の意見は BiggsTRC の意見と同じです。「ライブ」テーブルはコース レコードとの FK 関係を維持し、履歴テーブルは「ライブ」相手 (StudentScore) との関係のみを維持します。これにより、監査テーブルに孤児が存在しないことが達成されると思います。

ここで、回答に記載されていないことが他にもあります。現在のプロジェクトでは、コースの「状態」が何であったかを知るために、履歴テーブルで CourseHistory テーブルに FK を維持する価値があることがわかりました。 StudentScoreHistory 監査エントリ時の記録。もちろん、システムロジックによっては、それが重要な場合とそうでない場合があります。

同じ CourseId を複数回使用する可能性があるという懸念 (BiggsTRC への回答で) に対する私たちの解決策は、実際の CourseId ではなく、CourseHistory テーブルの PK 列を参照することでした。これを達成する方法についてはまだ確固たる決定がありません - 変更がなかったとしても Course レコードの監査エントリを作成するか、関連する Course に一致する CourseHistory レコードをルックアップするロジックを導入しようとするかStudentScoreHistory エントリ時の状態。

于 2011-05-19T04:53:03.513 に答える
1

あなたが説明したように論理的な削除のみを計画している場合、外部キーを使用しない理由はわかりません。

于 2011-04-26T18:07:42.623 に答える
0

「監査済み」行用に 2 番目のテーブル セットを作成するのではなく、監査機能を既存の運用スキーマに統合するだけです。あなたの目的は、特定の日付/災害の時点でのバックアップと復元ではなく、ユーザーまたは学生ごとの変更履歴を追跡することではないようです。それはアプリケーションの機能です。追加のフィールドは問題ないと思います。別のテーブルセットに追加する必要はありません。

バックアップと復元のプロセスに関する 1 つの問題は、スキーマの変更です。スキーマは時間の経過とともに変化する傾向があるため、バックアップから直接復元できない場合があります。監査関数を運用スキーマに組み込み続けると、追加の関数をサポートする必要があるときに何かを壊すことを心配する必要はありません。

于 2011-05-17T14:55:12.367 に答える