変更ログ/監査データベーステーブルに最適な設計ですか?[閉まっている]


114

さまざまな変更ログ/監査(何かが追加、削除、変更されたときなど)を格納するデータベーステーブルを作成する必要があります。特に詳細な情報を保存する必要がないので、次のように考えていました。

  • id(イベント用)
  • トリガーしたユーザー
  • イベント名
  • イベントの説明
  • イベントのタイムスタンプ

ここで何か不足していますか?明らかに、設計を改善し続けることはできますが、複雑にするつもりはありません(イベントタイプなどのテーブルを他に作成することは、私にとって複雑なため、問題外です)。


私はあなたの答えを読みました、そして、法について誰も話しませんでした。私は、いくつかの法律または優れた実践文書が(読み取り専用)監査テーブルをどのように実装しなければならないかを説明していることを知っています。しかし、これ以上の情報はありません。私はそれが存在することを知っています。私は21部11 CFRに監査証跡を考えている
バスティアンVandamme

回答:


69

私が取り組んでいるプロジェクトでは、監査ログもあなたが説明したような非常にミニマルなデザインから始まりました:

event ID
event date/time
event type
user ID
description

考え方は同じでした。物事をシンプルに保つことです。

しかし、このミニマルなデザインでは不十分であることがすぐに明らかになりました。典型的な監査は次のような質問に煮詰められました:

Who the heck created/updated/deleted a record 
with ID=X in the table Foo and when?

したがって、このような質問にすばやく(SQLを使用して)答えられるようにするために、監査テーブルに2つの列を追加することになりました。

object type (or table name)
object ID

監査ログの設計が本当に安定したのはそのときです(数年後)。

もちろん、最後の「改善」は代理キーを持つテーブルでのみ機能します。しかし、何だと思いますか?監査に値するすべてのテーブルには、このようなキーがあります。


この設計(「説明」ベースの監査証跡)で私が抱えていた唯一の問題は、その分野で使用される言語をローカライズすることです。
Sam Wilson

@Samこのような問題は発生しません。メッセージがシステムで生成されている場合は、翻訳文字列にここでキーを使用してください。
JCM

4
@ひる:2つ以上の異なる概念を1つの列に「混在」させると、遅かれ早かれ逆効果になることがよくあります。たとえば、イベントタイプとオブジェクトタイプを「混合」すると、「特定のタイプのすべてのオブジェクトのレコードを表示」や「特定のタイプのすべてのイベントのレコードを表示」などのクエリに影響します(クエリは複雑で、ほとんどの場合、動作が遅くなります)。
Yarik

3
これらの列に加えて、構造化された説明/構造化イベントのペイロード用の追加の列を含めることができます。この列には、イベントの詳細(複雑さは問わない)がコンピューター可読形式のXML / JSONで保持されます。シリアル化、クエリ(少なくともPostgres / MSSQLで)、推論が容易です。
turdus-merula

1
@ベンジャミン:答えはドメインモデル(別名ビジネスモデル)にあります。モデルでエンティティの同時作成が許可されている場合(論理トランザクションの一部としてなど)、まったく同じタイムスタンプを持つ複数のログレコードがあることに問題はありません。たとえば、(トランザクションとして)購入注文の作成にN注文アイテムの作成を含めることができる場合、対応するすべての1 + Nログレコードのタイムスタンプは同じになります。このようなログのその後の分析では、これを利用して、これらの1 + Nレコードを独立したレコードとしてではなく、論理トランザクションの要素として扱います。これが理にかなっているといいのですが。
Yarik、

24

また、古い値と新しい値、それらの元の列、および監査されているテーブルの主キーも監査詳細テーブルに記録します。監査テーブルが何のために必要か考えますか?誰がいつ変更したかを知りたいだけでなく、悪い変更が起こったときに、データをすばやく戻す方法も必要です。

設計中は、データを回復するためのコードを記述する必要があります。あなたが回復する必要があるとき、それは通常急いでいます、すでに準備されていることが最善です。


1
これは本当に良いことです。なぜ人々が最後の投稿を無視するのか分かりません。
Maddy.Shik

3
イベントソーシングは、履歴を維持しながらロールバック機能を提供するための代替アプローチです。
サム

23

テーブル/列名、更新元のコンピューター/アプリケーションなど、監査したい項目がいくつかあります。

これは、実際に必要な監査の詳細度とレベルによって異なります。

独自のトリガーベースの監査ソリューションの構築を開始しましたが、すべてを監査し、回復オプションも用意したいと考えていました。これは複雑すぎることが判明したため、トリガーベースのサードパーティツールであるApexSQL Auditをリバースエンジニアリングして、独自のカスタムソリューションを作成しました。

チップ:

  • 前/後の値を含める

  • 主キー(複合キーの場合)を格納するために3〜4列を含める

  • Robertによって既に提案されているように、メインデータベースの外部にデータを保存する

  • レポートの準備にまともな時間を費やします。特に、回復に必要となる可能性のあるレポートを準備します

  • ホスト/アプリケーション名の保存を計画する-これは、不審なアクティビティを追跡するのに非常に役立つ可能性があります


2
なぜそれを購入する代わりにリバースエンジニアリングするのですか?
Jowen、2015年

1
製品の管理を強化
Tebe

1
彼らがあなたを訴えなかったことを望みます。
ソーター、

9

ここと同様の質問には多くの興味深い答えがあります。私が個人的な経験から追加できる唯一のものは:

  1. 監査テーブルを別のデータベースに配置します。理想的には、元のデータから分離する必要があります。データベースを復元する必要がある場合、実際には監査証跡を復元する必要はありません。

  2. 合理的に可能な限り非正規化します。テーブルには、元のデータに対する依存関係をできるだけ少なくしたいとします。監査テーブルは、データを取得するためにシンプルかつ高速である必要があります。データにアクセスするために、他のテーブル間での複雑な結合やルックアップはありません。


8
正規化されていないデータは、適切なインデックスを持つ正規化されたデータと比較して、本当に速く読み込めますか?(すべての複製によってHDDからより多くのデータが読み取られるわけではありませんか?)
Sam

4

テーブルにあるもの:-

Primary Key
Event type (e.g. "UPDATED", "APPROVED")
Description ("Frisbar was added to blong")
User Id
User Id of second authoriser
Amount
Date/time
Generic Id
Table Name

汎用IDは更新されたテーブルの行を指し、テーブル名は文字列としてのそのテーブルの名前です。良いDB設計ではありませんが、非常に使いやすいです。すべてのテーブルに単一の代理キー列があるため、これはうまく機能します。


2
「金額」は何を表していますか?
turdus-merula 2018

それは金融アプリケーションなので、認可されているものの金額などです
WW。

4

一般に、カスタム監査(さまざまなテーブルの作成)は不適切なオプションです。データベース/テーブルトリガーを無効にして、一部のログアクティビティをスキップできます。カスタム監査テーブルは改ざんされる可能性があります。アプリケーションをダウンさせる例外が発生する可能性があります。堅牢なソリューションの設計の難しさは言うまでもありません。これまでのところ、私はこの議論で非常に単純なケースを見ています。現在のデータベースや特権ユーザー(DBA、開発者)から完全に分離する必要があります。すべての主流のRDBMSは、DBAでさえ無効にできない、秘密を改ざんできない監査機能を提供します。したがって、RDBMSベンダーが提供する監査機能を最初のオプションにする必要があります。その他のオプションとしては、サードパーティのトランザクションログリーダーまたはカスタムログリーダーがあり、分解された情報をメッセージングシステムにプッシュして、何らかの形で監査データウェアハウスまたはリアルタイムイベントハンドラーに変換します。要約すれば:ソリューションアーキテクト/「ハンズオンデータアーキテクト」は、要件に基づいてこのようなシステムの宛先を決定する必要があります。通常、ソリューションを開発者に引き渡すだけでは、あまりに深刻です。


3

これを行うには多くの方法があります。私の好きな方法は:

  1. mod_userソーステーブル(ログに記録するもの)にフィールドを追加します。

  2. ログを記録するフィールドと、log_datetimeおよびseq_numフィールドを含むログテーブルを作成します。 seq_num主キーです。

  3. 監視対象フィールドが変更されるたびに現在のレコードをログテーブルに挿入するトリガーをソーステーブルに作成します。

これで、すべての変更の記録と誰が変更したかがわかります。


それで... mod_userフィールドは何をするのですか?
conny

1
誰が変更したかを教えてください。コードの更新には、そのフィールドを現在のユーザーに設定するための何かを含める必要があります。
JosephStyons 2009年

では、削除についてはどうでしょうか?行を削除した場合、mod_user列の値をどのように処理しますか?
Kenn Cal

@KennCalトリガーは仮想テーブルを使用でき、同じトリガー内の前後のデータを確認できます。操作は関係ありません。stackoverflow.com/questions/6282618/...
ルナンカバリエリ

2
@KennCal正解です。削除トリガーはその情報を保存する必要があります。悪魔は詳細にありますが、SQL認証を使用している場合、トリガーは[select CURRENT_USER]を実行するだけで済みます。クライアントアプリケーションの場合、クライアントコードはそれが誰であるかを通知する必要があります。API呼び出しの場合は、削除するユーザーが呼び出しの必須パラメーターである必要があります。
JosephStyons 2016年

1

分離の原則によると:

  1. 監査データテーブルは、メインデータベースから分離する必要があります。監査データベースには多くの履歴データが含まれる可能性があるため、メモリ使用率の観点から、それらを分離しておくことは理にかなっています。

  2. トリガーを使用してデータベース全体を監査しないでください。サポートするためにさまざまなデータベースが混乱することになります。DB2、SQLServer、Mysqlなど用に1つ作成する必要があります。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.