ProgrammingリードSQL開発者

SQLのテーブルで監査メカニズムや変更追跡(変更履歴/ログ記録)を実装するにはどうすればよいですか?どのようなアプローチがあり、それぞれの利点と欠点は何ですか?その機能を設計する際に考慮すべき重要な点は何ですか?

Hintsage AIアシスタントで面接を突破

回答

監査メカニズム(ログまたは変更履歴)は、データのすべての変更を追跡し、透明性を確保するために実装されます。主にいくつかのアプローチがあります:

  1. 監査トリガー(Audit Triggers): 特殊なAFTER/BEFORE INSERT/UPDATE/DELETEトリガーが、行の古い状態および/または新しい状態を別の監査テーブルに保存します。利点 — アプリケーションに対する透明性;欠点 — DML操作の可能な遅延。

  2. 履歴を別のテーブルに隔離(History Table): レコードのバージョニングが適用され、変更時に"古い"行が履歴テーブルにコピーされ、タイムスタンプが付けられます。基本テーブルには最新のデータのみが含まれます。

  3. 組み込みメカニズム(Change Data Capture, Temporal Tables): たとえば、SQL ServerではSYSTEM_VERSIONED TEMPORAL TABLEを有効にすると、DBMSが自動的に変更履歴を保持します。

例(MySQL、監査用トリガー):

CREATE TABLE user_audit ( id INT AUTO_INCREMENT PRIMARY KEY, user_id INT, action VARCHAR(10), old_value TEXT, new_value TEXT, changed_at DATETIME ); DELIMITER // CREATE TRIGGER audit_user_update AFTER UPDATE ON users FOR EACH ROW BEGIN INSERT INTO user_audit (user_id, action, old_value, new_value, changed_at) VALUES (OLD.id, 'UPDATE', OLD.name, NEW.name, NOW()); END// DELIMITER ;

トリックのある質問

質問: 変更履歴の完全なプロトコルが必要な場合、UPDATEだけのaudit-triggerで十分ですか?

回答: いいえ。完全な履歴を得るには、すべての操作タイプにトリガーを組み合わせる必要があります:INSERT(新しい行をログ記録)、UPDATE(変更をログ記録)、DELETE(削除されたレコードをログ記録)。

例:

-- 各操作ごとに3つの別々のトリガーを作成する必要があります。さもなければ、履歴に"穴"ができます。

テーマの細部を知らなかったための実際のエラーの例


ストーリー1:会社は監査のためにUPDATEトリガーのみを使用しており、1年間削除されたレコードが記録されないことに気付かなかった。結果、インシデントを分析する際、重要なユーザーアカウントがいつ削除されたのかを特定できなかった。


ストーリー2:プロジェクトは変更の古い値と新しい値を1つのテキストフィールドにシリアル化されたJSONとして保持しており、分析が非常に困難になりました — 複雑なパーサーとレポート用の別のDBレプリカが必要になりました。


ストーリー3:高負荷のDBで、開発者はトリガーを通じて監査を実装し、ログテーブルのボリュームの増加を考慮しませんでした。時間が経つにつれて、履歴テーブルは基本テーブルの50倍になり、ストレージが過密になり、プロジェクト全体に障害を引き起こしました。