4

バックグラウンド:

私はバイテンポラル データベースを設計しています。ここでは、バイテンポラル テーブル間に 1:N の関係があります (M:N の関係もありますが、それらはコネクタ テーブルと 2 つの 1:N の関係でモデル化されているだけなので、それらは特別なものだと考えています)。 1:N 関係の場合)。

物事を説明するために、2 つのテーブルを持つ単純なケースを考えてみましょう。

|===============|        |==================|
|   tblOrder    |        |   tblOrderItem   |
|============== |        |==================| 
| - OrderId     |        | - OrderItemId    |
| - OrderNumber |        | - FK_OrderId     |
|===============|        | - Amount         |
                         |==================|

FK_OrderIdへの外部キーtblOrderです。

このデータベース モデルをバイテンポラルにするために、次の設計を考え出しました。

|===============|        |==================|        |====================|
|   tblOrder    |        |   tblOrderItem   |        |   tblVersions      |
|============== |        |==================|        |====================|
| - Id          |        | - Id             |        | - VersionId        |
| - OrderId     |        | - OrderItemId    |        | - VersionDate      |
| - OrderNumber |        | - FK_OrderId     |        |====================|
| - VersionId   |        | - Amount         |
| - IsDeleted   |        | - VersionId      |
| - StartDate   |        | - IsDeleted      |
| - EndDate     |        | - StartDate      |
|===============|        | - EndDate        |
                         |==================|

説明:

  • VersionId列はtblVersionsテーブルへの外部キーです。tblVersionsデータベースが変更されるたびに、テーブルにエントリが作成されます。データの現在の状態は、すべてのバージョンの合計になります。WHERE VersionDate < ...これにより、(節を介して) データベースの以前の状態を再構築することができます。これは、バイテンポラリティのトランザクション時間ディメンションです。
  • VersionDate`tblVersions table could also be avoided if we're just including the列を 2 つのデータ テーブルに挿入します。
  • StartDateおよびEndDate列は、バイテンポラリティーの有効な時間次元です。はい、EndDateちょっと冗長です。 だけでテーブルをモデル化できStartTimeます。
  • 2 つのテーブルのId列が新しい主キーです。同じエンティティに対して複数の行があるため (複数のバージョン、複数の有効期間の日付範囲)、エンティティの ID をテーブルの主キーにすることはできません。列OrderIdと列OrderItemIdはエンティティの ID ですが、テーブルの主キーではありません。新しい主キーを作成する代わりにId、主キーを として定義することもできます(OrderId, VersionId, StartDate)
  • エンティティが削除された場合は、新しいバージョン エントリと、エンティティ テーブル内の エントリを作成するだけIsDeleted = 1です。テーブル内の他のすべてのエントリ (挿入と更新) にはIsDeleted = 0.
  • の列はの列FK_OrderIdtblOrderitem参照しています。これは、もはや主キーではないため、(データベースの制約という意味で) 本当の外部キーではありません。しかし、どの OrderItems が特定の Order の一部であるかはまだわかります。OrderIdtblOrderOrderId

これはうまくいくようです。必要な CRUD クエリを作成し、バイテンポラル データを読み書きできるようになりました。

質問:

それが一貫して機能するためには、どのような制約が必要ですか?

制約を実装する方法には興味がありません (制約をFOREIGN KEYs またはUNIQUE制約、またはTRIGGERs、またはCHECKs などのデータベース制約として実装するかどうか)。必要な制約の種類を知る必要があるだけです。

私は答えとして投稿するつもりの制約の束を見つけました。しかし、おそらくもっとありますか?

4

1 に答える 1

0

(略語PIVT = 'point in valid time'を使用しています。これは、有効な時間ディメンション上の特定の時点を示します)

私がすでに考えていた制約は次のとおりです。

  • FK_VersionId:VersionId明らかに、列には標準の外部キー制約が必要です。
  • バイテンポラルの一意性:また、組み合わせ(OrderId, VersionId, StartDate)は一意である必要があります (および についても同じですtblOrderItem)。
  • 有効な時間のシリアル化:各エンティティと各バージョンについて、有効な時間に重複がないこと、つまり、列StartDateEndDateが重複しておらず、StartDate常に より早いことを確認する必要がありますEndDate
  • 削除の整合性:各エンティティと各 PIVT について、最大で 1 つの行が存在することを確認する必要があります。そのような行がある場合、その行のIsDeleted = 1にエンティティのバージョンがあってはなりません。
  • 参照整合性:各 OrderItem エンティティ、各バージョン、および各 PIVT について、 の値がFK_OrderId、特定の PIVT に存在する Order エンティティを識別する値に設定されていることを確認する必要があります。削除されていません (設定によりIsDeleted = 1)。
于 2013-10-03T16:16:10.633 に答える