Les clés étrangères peuvent être conditionnées ... en quelque sorte. Vous ne montrez pas la disposition de chaque table, voici donc une conception typique montrant vos relations:
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 )
);
Les Onlines et BrickMorters auraient la même structure de base mais avec StoreType limité à «O» ou «B» selon le cas.
Maintenant, vous voulez une référence d'une autre table à TransactionalStores (et à travers elle aux différentes tables de magasin) mais limitée aux kiosques et à BrickMorter. La seule différence serait dans la contrainte:
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 )
);
Dans ce tableau, la référence FK force StoreType à être «K», «O» ou «B» mais la contrainte de champ la limite en outre à «K» ou «B» uniquement.
Pour illustration, j'ai utilisé une contrainte de vérification pour limiter les types de magasins dans la table TransactionStores. Dans la vraie vie, une table de recherche StoreTypes avec StoreType étant un FK pour cette table serait probablement un meilleur choix de conception.