5

リレーショナル データベースでのスーパータイプ サブタイプの設計について質問があります。2 つのサブタイプ テーブルを持つスーパータイプがある場合、2 つのサブタイプ テーブルの PK に関連するスーパータイプの PK を FK として持つことになります。私がこのようなものを持っていたとしましょう:

タイプ

タイプ ID PK

スーパータイプ

ID PK タイプID FK

サブタイプA

ID PK,FK

サブタイプB

ID PK,FK

データベース側では、特定のタイプのスーパータイプ ID が適切なサブタイプ テーブルにのみ配置されるようにするにはどうすればよいでしょうか? たとえば、タイプ A のスーパータイプ ID を SubtypeB テーブルに入れたくありません。データベース側でこれが発生するのを簡単に防ぐ方法はありますか? これはコードで処理できることはわかっていますが、コードに誤りがあった場合はどうなるでしょうか? または、サブタイプ テーブルの 1 つに間違った ID を手動で入力した場合はどうなるでしょうか。データベース側でこれを不可能にする方法を探していると思います。

何か案は?おそらく、Supertype テーブルの PK は ID と TypeID の組み合わせであり、ID 列に一意の制約があり、両方のタイプのレコードが SuperType テーブルに含まれないようにする必要があります...そして、サブタイプ テーブルにはコンボ ID と TypeID PK が含まれます。 TypeID が適切なサブタイプ テーブルに適したタイプである必要があるという制約がありますか??

4

2 に答える 2

12

データベース側では、特定のタイプのスーパータイプ ID が適切なサブタイプ テーブルにのみ配置されるようにするにはどうすればよいでしょうか?

遅延制約をサポートする DBMS では、次のようなことができます。

ここに画像の説明を入力

に次の制約がありますSuperType

CHECK (
    (
        (SubtypeAId IS NOT NULL AND SubtypeAId = SuperTypeId)
        AND SubtypeBId IS NULL
    )
    OR
    (
        SubtypeAId IS NULL
        AND (SubtypeBId IS NOT NULL AND SubtypeBId = SuperTypeId)
    )
)

これらの特殊な循環 FK 1を CHECK と組み合わせることで、子の排他性と存在の両方が保証されます (CHECK はSuprerType.SubtypeAIdSuprerType.SubtypeBIdが非 NULL であり、 と一致することを確実にしますSuperTypeId)。子 FK (または DBMS がサポートしている場合は CHECK) を延期して、新しいデータを挿入するときのニワトリが先か卵が先かの問題を解決します。

1 SubtypeA.SubtypeAId参照SuperType.SuperTypeIdSuperType.SubtypeAId参照SubtypeA.SubtypeAId、他のサブタイプについても同様。

DBMS が遅延制約をサポートしていない場合は、(CHECK で) 両方のフィールドを NULL にすることを許可し、子の存在の強制を放棄することができます (まだ排他性を維持します)。


別の方法として、排他性のみ (プレゼンスではない) を次のように強制することもできます。

ここに画像の説明を入力

SuperType {SuperTypeId, TypeId}注: DBMS が "out-of-key" FK をサポートしていない場合は、重複する UNIQUE を追加する必要がある場合があります。

に次の制約がありますSubtypeA

CHECK(TypeId = 1)

そして、次の制約SubtypeB:

CHECK(TypeId = 2)

特定のサブタイプを示すために 1 と 2 を使用しました。一貫性がある限り、好きなものを使用できます。

TypeIdまた、サブタイプの計算列(Oracle 11仮想列など)を使用して、ストレージ領域を節約することを検討できます。


ところで、アプリケーション ロジックを通じてプレゼンスと排他性を強制することは、全体的な戦略としては悪くないと考えられています。ほとんどの場合、できる限り多くの整合性をデータベースに適用するように努力する必要がありますが、この特定のケースでは、上記の複雑さを回避するためにアプリケーション レベルで実行することが正当化されると考えられています。


そして最後に、継承を実装するための戦略は「すべてのクラスを別々のテーブルに」だけではありません。「すべてを 1 つのテーブルに」または「具体的なクラスを別のテーブルに」使用して継承を実装すると、サブタイプの存在と排他性の両方を強制することがはるかに簡単になります。

詳細については、この投稿をご覧ください。

于 2012-09-04T10:37:42.167 に答える
0

Use a trigger to propagate the new entry in the supertype table to the appropriate subtype table.

于 2012-09-04T10:02:59.940 に答える