条件付き外部キーの関係


14

現在、2つのエンティティ間に外部キーがあり、その関係をテーブルの1つのentityTypeを条件とするようにします。これがテーブルの階層です。これは、子から親へのFK参照を介して行われます

                  Store
            /                \
  Employees                    \
                             TransactionalStores
                            /       |         \
                     Kiosks         |          BrickMortars
                                 Onlines

現在、従業員から店舗へのFK関係があります

ALTER TABLE Employees ADD CONSTRAINT Employee_Store
            FOREIGN KEY (TransStoreId)
            REFERENCES TransactionalStores(StoreId)

条件を追加したい:

WHERE TransactionalStores.storeType != 'ONLINE_TYPE'

これは可能ですか、またはTransactionalStoresを2つの新しいsubType(PhysicalStoresおよびVirtualStoresなど)にサブクラス化する必要がありますか


回答:


17

外部キー条件付きで作成できます。各テーブルのレイアウトは表示しないため、関係を示す典型的なデザインを次に示します。

create table TransactionalStores(
    ID        int   not null auto_increment,
    StoreType char  not null,
    ..., -- other data
    constraint CK_TransStoreType check( StoreType in( 'B', 'K', 'O' )),
    constraint PK_TransactionalStores primary key( ID ),
    constraint UQ_TransStoreTypes unique( ID, StoreType ) -- for FK references
);
create table Kiosks(
    ID         int   not null,
    StoreType  char  not null,
    ..., -- other Kiosk data
    constraint CK_KioskStoreType check( StoreType = 'K' ), -- kiosks only
    constraint PK_Kiosks primary key( ID, StoreType ),
    constraint FK_Kiosks_TransStores foreign key( ID, StoreType )
        references TransactionalStores( ID, StoreType )
);

OnlinesとBrickMortersは同じ基本構造を持ちますが、StoreTypeは必要に応じて「O」または「B」のみに制限されます。

ここで、別のテーブルからTransactionalStoresへの(およびさまざまなストアテーブルへの)参照が必要ですが、キオスクとBrickMorterに限定されます。唯一の違いは制約にあります。

create table Employees(
    ID         int       not null,
    StoreID    int,
    StoreType  char,
    ..., -- other Employee data
    constraint PK_Employees primary key( ID ),
    constraint CK_Employees_StoreType check( coalesce( StoreType, 'X' ) <> 'O' )), -- Online not allowed
    constraint FK_Employees_TransStores foreign key( StoreID, StoreType )
        references TransactionalStores( ID, StoreType )
);

この表では、FK参照によりStoreTypeが強制的に「K」、「O」、または「B」のいずれかになりますが、フィールド制約によりさらに制限されて「K」または「B」のみになります。

説明のため、TransactionStoresテーブルのストアタイプを制限するためにチェック制約を使用しました。実際には、StoreTypesがそのテーブルのFKであるStoreTypesルックアップテーブルは、おそらくより良い設計選択でしょう。


9

外部キーを条件付きにすることはできないため、これは問題外です。ビジネスルールは、従業員が1つだけの物理的な店舗で働くことができるようです。それを考えると、スーパータイプのストアには、あなたが提案した2つのサブタイプがあります: 物理的およびオンラインです。各実店舗には1人以上の従業員が配置されており、各従業員は1つの実店舗にのみ割り当てられている必要があります。物理ストアには、2つのサブタイプ、Brick and MortarおよびKioskがあります。キオスクオンラインブリックとモルタルの 3つの直接的なサブタイプがあります-すべての店舗が所有するプロパティを隠します-物理的な場所で見つけることができるかどうか。現在、この設計では、サブタイプ名に固有のセマンティクスを理解して、オンラインストアには従業員がいないことを理解するために人間に依存しています。これは宣言されたスキーマでは容易に明らかではなく、DBMSが実施できる方法でその理解を表すためにトリガーの形式のコードを記述する必要があります。パフォーマンスに影響を与えないトリガーの開発、テスト、および保守は、「データベースプロフェッショナル向けの数学の応用」に示されているように、実装がはるかに難しいソリューションです。

最初にその種類の場所で、次に物理的な店舗の種類でストアをサブタイピングすることは、ビジネスルールに関してより正確な設計であり、ルールを実施するためのコードを記述する必要がなくなります。サブタイプの識別子として使用できる店舗ロケーションタイプとしてプロパティが明確に含まれると、従業員と実店舗の間の関係を直接作成できるため、外部キー制約だけでルールを完全に実装できます。ereは、Oracle SQL Developer Data Modelerで作成されたデータモデルで、Barker-Ellisを使用したスーパータイプとサブタイプを示しています。スーパーおよびサブタイプ用のボックスインボックス表記法。エレガントなプレゼンテーションを好む。ダイアグラムには、ルールも明確に表示されるようになりました。

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

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.