監査が必要なテーブルごとにトリガーと個別の履歴テーブルを使用して、データベースに単純な監査証跡を導入することを計画しています。
たとえば、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 パフォーマンス、ベスト プラクティス、設計の柔軟性など) の詳細を教えていただければ幸いです。
特定の目的と私たちの環境を探している人の利益のために:
目的:
- 重要なデータ履歴を維持する
- シナリオの再作成をサポートするユーザー アクティビティの監査を許可する
- 限られた範囲でユーザー アクティビティのロールバックを許可する
環境:
- トランザクション データベース
- すべてのテーブルで監査が必要なわけではありません
- 特に静的/参照データに対して、可能な範囲で論理的な削除を使用します
- 非常にトランザクションの多いテーブルで、物理的な削除を使用するものはほとんどありません