現在、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つの新しいサブタイプ(PhysicalStoresとVirtualStoresなど)にサブクラス化する必要がありますか?
外部キーcan条件付きにする...ソート。各テーブルのレイアウトは表示しないため、ここに関係を示す一般的なデザインを示します。
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テーブルのストアタイプを制限しました。実際には、StoreTypeがそのテーブルへのFKであるStoreTypesルックアップテーブルが、より優れた設計の選択となるでしょう。
外部キーは条件付きにすることができないため、問題外です。ビジネスルールでは、従業員は1つだけの物理ストアで働くことができるようです。それを前提として、ストアのスーパータイプには、PhysicalとOnlineの2つのサブタイプがあります。各実店舗には1人以上の従業員が配置され、各従業員は1つだけの実店舗に割り当てられる必要があります。実店舗には、Brick and MortarとKioskの2つのサブタイプがあります。 3つの直接サブタイプ-キオスク、オンライン、およびレンガとモルタル-各店舗が所有するプロパティを非表示にします-物理的な場所にあるかどうかにかかわらず。現在、デザインは人間に依存して、サブタイプ名に固有のセマンティクスを理解して、オンラインストアに従業員がいないことを理解しています。これは宣言されたスキーマではすぐにはわかりません。また、DBMSが実行できる方法でその理解を表現するために、トリガーの形式でcodeを記述する必要があります。本 データベース専門家のための応用数学 に示されているように、パフォーマンスに影響を与えないトリガーの開発、テスト、および維持は、実装するのがはるかに難しいソリューションです。
最初にその場所の種類をStoreでサブタイプし、次に物理的な店舗の種類の構造をしてからをサブタイピングすると、をビジネスルールに追加し、ルールを適用するコードを記述する必要をなくします。プロパティが、サブタイプの判別子として使用できる店舗ロケーションタイプとして明確に含まれると、従業員と実店舗との間に直接関係が作成され、外部キー制約のみでルールを完全に実装できます。 ereは Oracle SQL Developer Data Modeler で作成されたデータモデルで、スーパータイプとサブタイプのボックス表記で Barker-Ellis ボックスを使用してスーパータイプとサブタイプを示します。エレガントなプレゼンテーションが好きです。これで、図にルールも明確に示すことができます。