データに加えられた変更の履歴を保持する (簡単に実行できる) だけでなく、チェーン化された提案 (つまり、提案ごとの提案) を含む、データに対して提案された変更をいくつでも保存するデータ ストアが必要です。
これらの「変更」は、データベースに保存され、数分から数年の間の寿命を持つ、非常に長時間実行されるトランザクションと考えてください。
これらは作成 (提案) された後、ロールバック (本質的には削除) またはコミットされます。コミットされると、サード パーティに表示される有効なデータになります。
もちろん、提案された変更は矛盾した状態になる可能性があるため、これには何らかの形式の競合解決が必要です (たとえば、変更 A はレコードの削除を提案し、変更 B はそれを更新することを提案します - 変更 A が最初にコミットされた場合、変更 B は元に戻す必要があります)。
これを行うことができる既製の製品は見つかりませんでした。最も近いのは Oracle Workspace Manager でしたが、変更時の変更や提案された削除を表示する機能は提供されませんでした。これを達成できた唯一の方法は、バージョン管理されたテーブルに共通の列のセットを作成することです。
ルート ID : 必須 - レコードの最初のバージョンが作成されるときに、主キーと同じ値に 1 回設定されます。これは常に主キーを表し、レコードの各バージョンにコピーされます。リレーション列に名前を付けるときは、ルート ID を考慮する必要があります (例: PARENT_ID の代わりに PARENT_ROOT_ID)。ルート ID は初期バージョンの主キーでもあるため、実際の主キーに対して外部キーを作成できます。実際に必要な行は、以下で定義するバージョン フィルターによって決定されます。
変更 ID : 必須 - すべてのレコードは変更によって作成、更新、削除されます
Copied From ID : Nullable - null は新しく作成されたレコードを示し、not-null は更新/削除時にこの行が複製/分岐されたレコード ID を示します
有効開始日/時刻: Nullable - null は提案されたレコードを示し、not null はレコードがいつ最新になったかを示します。残念ながら、どのルート ID にも複数の null 値が存在する可能性があるため、一意のインデックスをルート ID/発効元に配置することはできません。(レコードごとに 1 つの提案された変更に制限したくない場合を除きます)
有効終了日/時間: Nullable - null は現在または提案されていることを示し、not null はそれがいつ履歴になったかを示します。技術的には必須ではありませんが、現在のデータを検索するクエリを高速化するのに役立ちます。このフィールドは手作業で編集すると破損する可能性がありますが、これが発生した場合は発効開始日/時刻から再構築できます。
Delete Flag : Boolean - 現在のレコードになったときにレコードを削除することが提案されている場合は true に設定されます。削除がコミットされると、それらの有効終了日/時間は有効開始日/時間と同じ値に設定され、現在のデータ セットから除外されます。
ある時点でのデータの現在の状態を取得するクエリは次のようになります。
SELECT * FROM table WHERE EFFECTIVE_FROM <= :Now AND (EFFECTIVE_TO IS NULL OR EFFECTIVE_TO > :Now)
変更に従ってデータの現在の状態を取得するクエリは次のようになります。
SELECT * FROM table WHERE (CHANGE_ID IN :ChangeIds OR (EFFECTIVE_FROM <= :Now AND (EFFECTIVE_TO IS NULL OR EFFECTIVE_TO > :Now) AND ROOT_ID NOT IN (SELECT ROOT_ID FROM table WHERE CHANGE_ID IN :ChangeIds)))
この 2 番目のクエリには、提案された変更データで現在のデータをオーバーレイするための 1 番目の時間ベースのクエリが含まれていることに注意してください。
変更 ID 列は、変更時の変更機能を提供する親 ID 列 (null 可能) も含む変更テーブルの主キーを参照します。したがって、2 番目のクエリは、単一の変更 ID ではなく変更 ID を参照します。クライアントの変更時の変更シナリオで複数のバージョンをフィルタリングしていますが、SQL を使用していないため、これらのクエリでは表示されません (クライアントはメモリ内に変更 ID のリンクされたリストを持っており、行の複数のバージョンが取得された場合リンクされたリストを使用して、使用するバージョンを決定します)。
私が使用できる既製の製品を知っている人はいますか? このバージョン管理を自分で処理するのは膨大な作業であり、あらゆる種類の問題が発生します。