Le chiavi esterne possono essere condizionate ... in un certo senso. Non mostri il layout di ogni tabella, quindi ecco un tipico design che mostra le tue relazioni:
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 )
);
Online e BrickMorters avrebbero la stessa struttura di base ma con StoreType vincolato solo a 'O' o 'B' come appropriato.
Ora vuoi un riferimento da un'altra tabella a TransactionalStores (e attraverso di essa alle varie tabelle del negozio) ma limitato a Kiosks e BrickMorter. L'unica differenza sarebbe nel vincolo:
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 questa tabella, il riferimento FK impone che StoreType sia 'K', 'O' o 'B' ma il vincolo di campo lo limita ulteriormente a 'K' o 'B'.
Per esempio, ho usato un vincolo di controllo per limitare i tipi di negozi nella tabella TransactionStores. Nella vita reale, una tabella di ricerca StoreTypes con StoreType come FK per quella tabella sarebbe probabilmente una scelta di design migliore.