Fremdschlüssel können bedingt werden ... irgendwie. Sie zeigen nicht das Layout jeder Tabelle an, daher sehen Sie hier ein typisches Design, das Ihre Beziehungen zeigt:
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 )
);
Die Onlines und BrickMorter hätten die gleiche Grundstruktur, wobei StoreType jedoch auf "O" oder "B" beschränkt wäre.
Jetzt möchten Sie einen Verweis von einer anderen Tabelle auf TransactionalStores (und damit auf die verschiedenen Speichertabellen), jedoch auf Kiosks und BrickMorter. Der einzige Unterschied wäre in der Einschränkung:
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 )
);
In dieser Tabelle erzwingt die FK-Referenz, dass StoreType entweder "K", "O" oder "B" ist, die Feldbeschränkung beschränkt sie jedoch weiter auf "K" oder "B".
Zur Veranschaulichung habe ich eine Check-Einschränkung verwendet, um die Speichertypen in der TransactionStores-Tabelle einzuschränken. Im wirklichen Leben wäre eine StoreTypes-Nachschlagetabelle mit StoreType als FK für diese Tabelle wahrscheinlich die bessere Wahl für das Design.