Phím nước ngoài có thể được thực hiện có điều kiện ... loại. Bạn không hiển thị bố cục của mỗi bảng, vì vậy đây là một thiết kế điển hình thể hiện các mối quan hệ của bạn:
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 và BrickMorters sẽ có cùng cấu trúc cơ bản nhưng với StoreType bị ràng buộc chỉ 'O' hoặc 'B' là phù hợp.
Bây giờ bạn muốn có một tài liệu tham khảo từ một bảng khác đến TransactionalStores (và thông qua nó tới các bảng cửa hàng khác nhau) nhưng giới hạn ở Kiốt và BrickMorter. Sự khác biệt duy nhất sẽ là trong các ràng buộc:
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 )
);
Trong bảng này, tham chiếu FK buộc StoreType phải là 'K', 'O' hoặc 'B' nhưng giới hạn trường tiếp tục giới hạn nó chỉ ở 'K' hoặc 'B'.
Để minh họa, tôi đã sử dụng một ràng buộc kiểm tra để giới hạn các loại cửa hàng trong bảng TransactionStores. Trong cuộc sống thực, một bảng tra cứu StoreTypes với StoreType là FK cho bảng đó có lẽ là một lựa chọn thiết kế tốt hơn.