ライブ オブジェクトとドラフト オブジェクトの両方が必要であるというひねりを加えたオブジェクトのバージョン管理の実装を検討しています。潜在的に恐ろしいハックなしでそれが可能であるかどうか疑問に思っているので、これに関する誰かの経験からの洞察を使用できます。
例のためにタグ付きの投稿に分割しますが、私のユースケースはもう少し一般的です (ゆっくりと変化する次元を含む - http://en.wikipedia.org/wiki/Slowly_changeing_dimension )。
posts テーブル、tags テーブル、post2tag テーブルがあるとします。
posts (
id
)
tags (
id
)
post2tag (
post_id fkey posts(id),
tag_id fkey tags(id)
)
私はいくつかのことが必要です:
- 削除された行を含め、任意の日時に投稿がどのように見えるかを正確に示すことができます。
- 完全な監査証跡のために、誰が何を編集しているかを追跡します。
- 参照整合性を維持するために、具体化されたビュー (「ライブ」テーブル) のセットが必要です (つまり、ログは開発者に対して透過的である必要があります)。
- ライブおよび最新のドラフト行に対して適切に高速である必要があります。
- 下書き投稿とライブ投稿を共存させることができます。
さまざまなオプションを調査してきました。これまでのところ、私が思いついた最高のもの (ポイント #4/#5 を除く) は、SCD type6 ハイブリッド セットアップに少し似ていますが、現在のブール値を持つ代わりに、現在の行の具体化されたビューがあります。すべての意図と目的のために、次のようになります。
posts (
id pkey,
public,
created_at,
updated_at,
updated_by
)
post_revs (
id,
rev pkey,
public,
created_at,
created_by,
deleted_at
)
tags (
id pkey,
public,
created_at,
updated_at,
updated_by
)
tag_revs (
id,
public,
rev pkey,
created_at,
created_by,
deleted_at
)
post2tag (
post_id fkey posts(id),
tag_id fkey tags(id),
public,
created_at,
updated_at,
updated_by
)
post2tag_revs (
post_id,
tag_id,
post_rev fkey post_revs(rev), -- the rev when the relation started
tag_rev fkey tag_revs(rev), -- the rev when the relation started
public,
created_at,
created_by,
deleted_at,
pkey (post_rev, tag_rev)
)
ピリオド (created_at、deleted_at) のインデックスを維持するために pg_temporal を使用しています。そして、トリガーを使用してさまざまなテーブルを同期させます。ヤダヤダヤダ... 下書きが公開されずにリビジョンに保存されるように、投稿/タグの編集をキャンセルできるトリガーを作成しました。それはうまくいきます。
post2tag の下書き行関連の関係について心配する必要がある場合を除きます。その場合、すべての地獄が解き放たれます。これは、何らかの設計上の問題があることを示唆しています。でもアイデアが尽きた…
データの重複を導入することを検討しました (つまり、ドラフト リビジョンごとに導入された n 個の post2tag 行)。この種の作品は、私が望むよりもずっと遅くなる傾向があります。
「最後のドラフト」にドラフトテーブルを導入することを検討しましたが、これはすぐに非常に見苦しくなります。
私はあらゆる種類のフラグを検討しました...
質問: 行バージョン制御環境でライブ行と非ライブ行を管理する一般的に受け入れられている方法はありますか? そうでない場合、何を試してかなりの成功を収めましたか?