我如何最好地設計一個數據庫,其中我有一個球員表(主鍵player_id),我想將它們配對爲兩個球隊,以便數據庫可以強制約束每個球員球隊組成正好兩位球員和每位球員是最多一個球隊?用於約束強制配對的數據庫設計
我可以想到兩個解決方案,但我都不太滿意。
一種可能性是有兩列player1_id和player2_id是指着球員表player_id列獨特外鍵。需要進行額外的檢查,以便沒有球員同時參加一個球隊的球員1和另一個球隊的球員2。
是在我腦海中的另一種可能是給玩家表和球隊表具有唯一外鍵在播放表中的player_id塔和第二外鍵一個團隊成員表連接指向團隊表的主鍵。這裏必須補充一點,每個團隊都有兩個成員。
是否有更好的設計可以簡化對約束的檢查?
如果很重要:我使用的數據庫是PostgreSQL 8.4,我更喜歡它的功能強大的rule system觸發器儘可能。
編輯:基於AlexKuznetsov
的回答解決方案。它並不感到完美的我,但我喜歡它比我以前好多了。我修改了Alex的解決方案,因爲我不想讓隊員擁有外鍵,因爲有一個應用程序階段,玩家可以註冊。
create table TeamMemberships(
player_id int not null unique references Players(player_id),
team_id int not null references Teams(team_id),
NumberInTeam int not null check(NumberInTeam in (0,1)),
OtherNumberInTeam int not null, -- check(OtherNumberInTeam in (0,1)) is implied
check(NumberInTeam + OtherNumberInTeam = 1)
foreign key (team_id, OtherNumberInTeam) references TeamMemberships(team_id, NumberInTeam),
primary key (team_id, NumberInTeam)
);
此定義確保團隊成員資格成對(並且將成對插入)。現在球員最多隻能有一個球隊,球隊可以有0個或2個球員。爲了確保每個團隊都有成員,我可以在團隊表中添加一個指向任何兩個成員的外鍵。但是像Erwin一樣,我不是延遲約束檢查的粉絲。任何想法如何改善這方面呢?還是有一個完全不同的,更好的方法?
PS:這些方法也適用於n> 2的球員。只需用NextNumberInTeam替換OtherNumberInTeam和值(即約束)NumberInTeam + 1 mod n即可。
有postgres物化視圖嗎? – FerranB 2009-07-14 20:31:20