每个表 People 和 Team 代表实体。交集或联结表各自代表实体之间的关系。如果您有多个可能的关系,那么拥有多个联结表是有意义的。
您暗示某些关系可能是相互排斥的。这是一个足够简单的问题来解决。
create table CaptainOrMember(
PersonID int not null,
TeamID int not null,
C_or_M char( 1 ) not null,
constraint PK_CaptainOrMember primary key( PersonID, TeamID ),
constraint FK_CaptainOrMember_Person foreign key( PersonID )
references People( ID ),
constraint FK_CaptainOrMember_Team foreign key( TeamID )
references Team( ID ),
constraint CK_CaptainOrMember_OneOrOther check( C_or_M in( 'C', 'M' )
);
这定义了船长和成员关系。只能输入一个人 <-> 团队条目,并且必须用“C”或“M”指定。因此,一个人可以是队长或团队成员,但不能两者兼而有之。
它具有将一个联结表用于两个关系的额外优势。
也就是说,除非您有一些仅船长和仅会员数据要添加到关系元组中。然后您可以添加两个“子联结”表。在这里他们是为了说明。
alter table CaptainOrMember add constraint UQ_CaptainOrMember_OneOrOther unique( PersonID, TeamID, C_or_M );
create table Captains(
PersonID int not null,
TeamID int not null,
C_or_M char( 1 ) not null,
...,
..., <Captain related data>
...,
constraint PK_Captains primary key( PersonID, TeamID ),
constraint CK_Captains_OneOrOther check( C_or_M = 'C' ),
constraint FK_Captains_Captain foreign key( PersonID, TeamID, C_or_M )
references CaptainOrMember( PersonID, TeamID, C_or_M )
);
create table Members(
PersonID int not null,
TeamID int not null,
C_or_M char( 1 ) not null,
...,
..., <Member related data>
...,
constraint PK_Members primary key( PersonID, TeamID ),
constraint CK_Members_OneOrOther check( C_or_M = 'M' ),
constraint FK_Members_Member foreign key( PersonID, TeamID, C_or_M )
references CaptainOrMember( PersonID, TeamID, C_or_M )
);
如果CaptainOrMember 表中的条目将特定人员定义为特定团队的队长,则该人员和该团队的组合不能插入到Members 表中。它只能存在于 Captains 表中。反之亦然。