你有一個「一對一」的關係。這在SQL中很棘手,使用三列的方法是一個很好的方法。爲什麼?它允許正確的外鍵聲明。
我會找一個表定義像這樣:
create table Awards (
awardsId int identity primary key,
. . .
supplierId int,
employeeID int,
otherID int,
beneficiaryType as (case when supplierId is not null then 'S'
when employeeId is not null then 'E'
when otherId is not null then 'O'
end),
constraint chk_beneficiary
check ((supplierId is not null and employeeId is null and otherid is null) or
(supplierId is null and employeeId is not null and otherid is null) or
(supplierId is null and employeeId is null and otherid is not null)
),
constraint fk_awards_supplierId foreign key (supplierId) references Suppliers(supplierId),
constraint fk_awards_employeeId foreign key (employeeId) references Employees(employeeId),
constraint fk_awards_supplierId foreign key (otherId) references Others(otherId)
);
如果真的是不尋常的是另一種類型的受益人的加入,則數據庫維護是不是一個大問題。
我要指出,你也可以做上面的「通用」列和持久化計算列:
create table Awards (
awardsId int identity primary key,
. . .
beneficiaryType char(1) not null,
beneficiaryId int not null,
constraint chk_awards_beneficiaryType check (beneficiaryType in ('E', 'S', 'O')),
supplierId as (case when beneficiaryType = 'S' then beneficiaryId end) persisted,
employeeID as (case when beneficiaryType = 'E' then beneficiaryId end) persisted,
otherID as (case when beneficiaryType = 'O' then beneficiaryId end) persisted,
constraint fk_awards_supplierId foreign key (supplierId) references Suppliers(supplierId),
constraint fk_awards_employeeId foreign key (employeeId) references Employees(employeeId),
constraint fk_awards_supplierId foreign key (otherId) references Others(otherId)
);
由於計算列有才能被堅持使用外鍵,這樣做不節省空間。然而,添加新類型的只是在做一個事情:
- 更改
check
約束爲beneficiaryType
- 添加一個新的計算列
- 添加一個新的外鍵約束
這確實要求所有表的所有id具有相同的類型。但是,我(幾乎)總是使用標識列作爲主鍵,所以在我設計的任何數據庫中都會自動實現。
對不起,我不明白這個問題。 –
@ZoharPele我編輯了模式,我第一次錯了。 – madlan