我如何最好地设计一个数据库,其中我有一个球员表(主键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