4

更新可能なさまざまなフィールドを持つテーブルがあります。それを呼び出してtable1、次のフィールドがあると仮定します。

user VARCHAR2
first_name VARCHAR2
last_name VARCHAR2

私の質問: これらのフィールドへの編集を追跡したいと思います。これらのフィールドを更新できるアプリケーションを持っていますが、いつフィールドが編集されたか、がフィールドを編集したか、どのフィールドが編集れたかを追跡したいと考えています。

履歴テーブルを作成できます。

date_edited DATE
who_edited VARCHAR2
field_name_edited VARCHAR2

フィールド名が変更された場合はどうなりますか?..それは、field_name_edited存在しないフィールドを参照することを意味します。これはばかげたアプローチのようです。

この種のことを行う一般的な方法があるはずですか?

どうもありがとう。

編集

Oracle DB を使用しています - 新しい質問タグを参照してください。

4

2 に答える 2

6

「この種のことを行う一般的な方法があるに違いありませんか?」

あなたのアプローチは一般的ですが、見当違いのものであるため、そうではありません。列レベルでの変更の追跡は、いくつかの理由で不十分です。

  1. 更新が複数の列に触れるとコストがかかります (更新された行ごとに複数の監査レコードを挿入します)。
  2. 特定の時点でのレコードの状態の首尾一貫した全体像を組み立てるのは困難です (プログラムが複雑で、起動コストが高くなります)。
  3. 特定の列が変更されたかどうかをテストするエレガントな方法はありません。
  4. 列の値を格納するのは面倒です (実装では通常、さまざまなデータ型を文字列に変換して処理します)。

(あなたが提案した表は、最後の点を扱っていません。これは見落としだと思います。変更された値を追跡しない監査証跡にはほとんど価値がありません)。

では、一般的な解決策は何ですか?行レベルの履歴テーブル。レコード全体をジャーナリング テーブルに挿入するトリガー (DATE_EDITED や WHO_EDITED などのメタデータ列と一緒に)。これらのトリガーは、データ ディクショナリから簡単に生成できます。

確かに、このアプローチでは、特定のトランザクションで編集された列を特定するのが難しくなります。でも:

  1. これを行うのは難しいですが、不可能ではありません。これは SQL で実装できます (分析 LAG などを使用) が、実際には、人間は補助なしで変更を見つけるのが得意です。
  2. このコストは、監査サブシステムによって負担されます。監査サブシステムは、実際には (要件の内容に関係なく) あまり使用されず、アプリケーションのコア部分よりもはるかに使用されません。したがって、ジャーナリングを高価にするよりも、処理コストを監査サブシステムにオフロードすることをお勧めします。

また、前述したように、行レベルのジャーナリングでは、監査レコードの生成と取得の両方で、列レベルよりもコストが低くなります。


あなたのコメントでは、Oracle のTotal Recall 製品に関する記事にリンクしています。これは実際には非常に洗練されたソリューションであり、メイン システムへの影響が非常に少なく、テーブルの履歴状態を簡単に復元できます。問題は、12c より前のバージョンでは、Enterprise Edition に有料の追加料金がかかるため、コストが高くなることです。(実際、それ自体が個別の製品ではなく、高度な圧縮オプションの一部になりました)。12c では、Basic Flashback Data Archive (Total Recall の新しい名前) はすべてのエディションで利用できますが、ジャーナリング テーブルを圧縮するには Advanced Compression Option を購入する必要があります。


「行の編集を [保存する] ことをお勧めします。したがって、冗長データを保存します。」

うん。最近のストレージは通常安価です。冗長なデータを格納するコストは、通常、レコードの効率的な書き込みと検索のために支払うのに十分な代償です。

「元の列のリテラル名をコピーする必要があります」

ジャーナリングは、データ テーブルごとに 1 つの監査テーブルを使用します。監査テーブルはライブ テーブルの構造と一致し、トランザクションに関連するメタデータを保持する列がいくつか追加されています。監査列は、類似のデータ列と同じ名前を持つことが期待されます。(特に、データ ディクショナリから監査テーブルの DDL を生成できるため、他のことを行うのはばかげています。)

于 2012-11-04T14:49:28.393 に答える
0

免責事項これは、私が数年前に同様の状況で使用したものです。当時、私たちがしなければならなかったすべての結合とトリガーで、私はそれがあまり好きではありませんでした. 誰かがより良いアプローチを持っている場合は、投稿してください!

私の理解では、フィールド名が変更される可能性があると思われる場合は、フィールド情報を追跡するマスター データ テーブルが必要です。マスター データ用に 1 つの履歴テーブルと、実際のユーザー テーブル用に 1 つの履歴テーブルが必要です。上記のポスターの 1 つが言ったように、テーブルの 1 つが変更されたときに、トリガーを使用して正しい履歴テーブルに書き込むことができます。

table editable_fields

id
field_name
created/modified_by/date

サンプル エントリ = {(1, user), (2, first_name), (3, last_name)}


table user

id
field1_value
field2_value
field3_value
created/modified_by/date

エントリの例 = {(1, johnsmith, John, Smith), (2, janedoe, Jane, Doe)}


table user_fields_mapping

id
-- FKs to editable_fields.id
field1_editable_id
field2_editable_id
field3_editable_id

サンプル エントリ = {(1, 1, 2, 3), (2, 1, 2, 3), (3, 1, 2, 3)}

于 2012-11-04T13:47:09.193 に答える