2011-08-22 6 views
0

私の質問はDatabase Design for Revisions?に関連していますが、もっと複雑です。多対多のリビジョンのデータベース設計ですか?

私はそれらの間に多対多の関係を持つ2つのテーブルを持っています。

A: A.id, A.data, A.last_change_time 
B: B.id, B.data 
A_B: A_B.A_id, A_B.B_id, A_B.connected_since_time, A_B.some_status_enum 

A_Bコネクタテーブルはリビジョンをサポートする必要があります。 Aの要素とBの要素との間の接続が削除された場合、以前に存在していた履歴情報を保持する必要があります。接続状態が変更された場合、古い状態に関する履歴情報を保持する必要があります。私は生成に必要なレポートの

いくつかは以下のとおりです。(今)すべてでBに接続されていない内のすべての要素の

  1. 一覧。
  2. Bの少なくとも1つの要素に特定のステータスで接続されているAのすべての要素のリスト。
  3. 一度接続されたが接続されていないすべてのA-Bペアのリスト。
  4. Aの最後の変更時刻が接続時刻の後のすべてのA-B接続のリスト。
  5. Aの最後の変更時刻が、接続時間をステータスでグループ化した後のすべてのA-B接続の数。

私は接続テーブルにA_B.is_currentブール値フィールドを単に追加すると考えました。接続が削除されたら、単にis_currentをfalseに設定します。ステータスが変わると、古いレコードに対してはis_currentをfalseに設定し、新しいステータスで新しいレコードを追加します。

これまでによく似た質問に対する回答は、「is_current」が不適切な設計であり、より良い解決策が必要であると主張しています。これまでのソリューションでは、単一テーブル内のレコードのリビジョンと、それらのリレーションの関係については言及されていませんでした。

is_current列を使用して多対多接続の履歴を追跡するのは間違っていますか?それが間違っている場合、それはどんな問題を引き起こすか?よりよい解決策は何ですか?

答えて

1

通常...

  • は2つの余分な列を持っている:ValidFromDateTimeValidToDateTime
  • 主キーがValidToDateTimeがNULLまたはセンチネル値(例えば99991231)することができ、その後A_id, B_id, ValidFromDateTime
  • ある

新しいリビジョンが発生すると、 "現在の行"のValidToDateTimeが入力され、新しい行がValidFromDateTimeのdatetime値と同じです。これがビジネスルールの場合は、ValidToDateTimeを設定します。

これは、任意の時点のためなど(またはその欠如)を述べる

与えあなたのクエリは、その後非常に簡単

  1. あるA_ID
  2. 上に存在しないA_ID
  3. 上に存在している上に存在しますValidToDateTimeを持つA_IDはNULLではない(現在の行はありません)
  4. また、ValidToDateTimeとlast_change_timeを比較するA_IDのEXISTS
  5. LEFT JOIN(4と同じ条件)で集計
+0

この音声は論理的です。 nullで記録するValidToは現在のレコードです。関係のステータスを変更すると、古いレコードが現在の時刻で更新されます。 – Muxecoid

0

is_currentフラグを使用したときに見られる主な問題は、最新のものになったレコードが最新であるかどうかを判断することができないことです。私は通常、現在の日付の開始日を示す日付フィールドを追加します。次に、あなたのクエリは通常、最新の日付で行を取得するだけです。

+0

私は既にconnected_since_timeフィールドを持っています。問題は、いくつかのレポートでは、このケースではすべての接続されたペアのリストを出力する必要があるということです。is_currentは時間によるソートと最大値の取得よりも論理的なアプローチです。リビジョンタイムのみを有する別の問題は、接続の削除である。 – Muxecoid

+0

削除を念頭に置いて、ValidToフィールドを導入したgbnの応答が問題を解決するはずです。 is_currentフィールドだけでは、特定の時点で何が有効であったかを知ることは不可能です。 – NickHeidke