13

バージョン管理されたデータを中心に展開するデータ モデルを設計するための最良の方法について、意見を求めています。1 対多および多対多の関係があり、バージョンごとにすべて変更できます。

最終的な目標は効率的な比較であり、可能であればデルタのみを保存するといういくつかの異なる戦略を探しています。

4

1 に答える 1

17

イントロ

これは実際にはかなり難しい問題です。

オブジェクトのバージョン管理は簡単です。それらの間の接続のバージョン管理はそれほど多くありません-いくつかの設計上の決定を行う必要があります。例えば:

  • 履歴の任意の時点でグラフ全体の「スナップショット」を取得する必要がありますか?
  • 完全な削除と、削除されたオブジェクトと接続を復元する機能が必要ですか?
  • 速度(およびバージョン間でグラフ全体をコピーしてもかまいません)またはスペースのどちらが好きですか?

その上、ほとんどの「サポート」テーブルはおそらく「バージョン対応」である必要があります。

設計

もし私があなたなら、私はおそらく次の出発点から自分の道を歩むでしょう:

ここに画像の説明を入力してください

OBJECTとCONNECTIONの間の記号は、「カテゴリ」(別名、継承、サブクラス、一般化階層など)です。

この設計の背後にある基本的な考え方は、「スナップショット」、「復元」、および「デルタ」機能をサポートすることです。

  • グラフ全体にはグローバルバージョン(別名「世代」)があり、それらの間のデルタのみを格納します。
  • すべてのオブジェクトは、そのグローバル世代でバージョン管理されます(ローカルのオブジェクト固有のバージョンとは対照的です)。
  • 接続はオブジェクトであるため、バージョンも設定されます。
  • オブジェクトのセットがリポジトリに入るたびに、新しいGENERATIONが挿入され、次のようになります。
    • 挿入されたオブジェクトは、OBJECTおよびOBJECT_VERSIONに挿入されます。
    • 変更されたオブジェクトがOBJECT_VERSIONに挿入されます。
    • 削除されたオブジェクトは、DELETED=trueでOBJECT_VERSIONに挿入されます。
    • 復元されたオブジェクトは、DELETED=falseでOBJECT_VERSIONに挿入されます。ところで、これにより、削除/復元サイクルを複数回繰り返すことができます。
    • 残りのオブジェクトは変更されていないため、変更されていないデータをコピーするスペースを無駄にしません。
  • 接続を実際に変更することはできません。子オブジェクトを新しい親に「移動」するには、古い接続を削除し(上記のようにDELETEDを設定して)、新しい接続を挿入します。実際、削除は接続でサポートされる唯一の種類の変更です。

クエリは次のようになります。

  • すべてのバージョンから単一のオブジェクトを取得するには、目的の世代よりも高くない最も高いオブジェクトを選択します。このバージョンのDELETEDがtrueの場合、オブジェクトはこの世代に存在しません。
  • 目的の世代でグラフ全体のスナップショットを取得するには、すべてのオブジェクトに対して上記を実行し、メモリ内グラフを作成します。一方または両方のエンドポイントが削除されている接続を削除します。
  • オブジェクトを特定のオブジェクトに接続するには、CONNECTIONを再帰的にトラバースしますが、上記の基準を満たさないオブジェクトに遭遇したらすぐに再帰をカットします。

オブジェクトA、B、Cを配置する必要があるとします。ここで、AはBとCの親です。

generation: 0

      A0
     /  \
   B0    C0

新しいオブジェクトDを追加します。

generation: 0 1

      A0
     / | \
   B0  C0 D1

AとCを変更し、Bを削除します。

generation: 0 1 2

      A0
      A2
     / | \
   B0  C0 D1
   B2* C2

   (*) OBJECT_VERSION.DELETED is true

CをAからDに移動します。

generation: 0 1 2 3

      A0
      A2
     / |* \
   B0  C0  D1
   B2* C2  |
           C3

等...

いくつかのMusings

この設計は、一貫性のない削除を伴う異常に対して開かれています。データベースは、削除されたオブジェクトと削除されていないオブジェクトの接続、または接続を削除せずにオブジェクトの1つを削除状態に進化させることから自身を防御しません。両方のエンドポイントを調べるまで、接続が有効かどうかはわかりません。データが階層的である場合は、代わりに「到達可能性モデル」を使用できます。ルートオブジェクトから到達できる場合、オブジェクトは削除されません。オブジェクトを直接削除することはありません。オブジェクトへのすべての接続を削除するだけです。これは、フォルダ/ファイルなどの階層でうまく機能します。「上」から始めて、目的のオブジェクトに到達するまで下に向かって検索します。

「不変」接続の代わりに、OBJECT_VERSIONからCONNECTION_VERSIONを継承し、そこにPARENT_ID / CHILD_IDを配置し、識別関係を使用して、ひし形の依存関係が正しくモデル化されていることを確認します。これは、移動の履歴を追跡する必要がある場合に役立ちます。

もちろん、これらは単なる幅広いストロークです。あなたが自分の道を見つけてくれることを願っています...

于 2012-10-19T20:19:12.370 に答える