Postgresql

條件外鍵關係

  • February 13, 2019

我目前在兩個實體之間有一個外鍵,我想讓該關係以其中一個表的 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 子類化為兩個新的子類型(例如 PhysicalStores 和 VirtualStores)

外鍵可以是有條件的……有點。您沒有顯示每個表格的佈局,因此這裡有一個顯示您的關係的典型設計:

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(並通過它到各種儲存表),但僅限於 Kiosks 和 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 查找表可能是更好的設計選擇。

引用自:https://dba.stackexchange.com/questions/113122