我正在设计一个数据库,但无法弄清楚如何建立参照完整性。
我有以下表格
CREATE TABLE Groups
(
GroupId INT PRIMARY KEY,
GroupName VARCHAR(50)
)
CREATE TABLE GroupMembers
(
GroupId INT NOT NULL,
MemberId INT NOT NULL,
MemberName VARCHAR(50),
CONSTRAINT pk_GroupMember PRIMARY KEY (GroupId, MemberId)
)
CREATE TABLE Missions
(
MissionId INT PRIMARY KEY,
GroupId INT NOT NULL,
MissionName VARCHAR(50)
)
CREATE TABLE MissionRollAssignments
(
MissionId INT NOT NULL,
MemberId INT NOT NULL,
MemberRoll VARCHAR(50) --This will probably become RollId and move details to another table
)
每个任务都将为相应组的部分/全部成员分配任务。每个小组都会有几个任务,但每个小组只有一个任务在特定时间内有效。
我的问题是:
是否可以对滚动分配强制执行参考完整性,以便仅限成员 选择相应组(由MissionId给出)?我知道我可以从GUI中过滤掉这个,但是如果我可以在考虑Mission中指示的GroupId的同时从MissionRollAssignments到GroupMembers创建一个FK约束,我会感觉更舒服。
第二个问题是,如果你们认为这是建立我的域名的好方法,或者我应该尝试不同的方法。
提前感谢您提供任何帮助。
最好的问候,
AWER
答案 0 :(得分:2)
您可以将GroupId放入MissionRollAssignments,然后添加两个约束,如下所示:
ALTER TABLE MissionRollAssignments
ADD CONSTRAINT fk1 FOREIGN KEY (GroupId, Memberid)
REFERENCES GroupMembers (GroupId, Memberid);
ALTER TABLE MissionRollAssignments
ADD CONSTRAINT fk2 FOREIGN KEY (GroupId, MissionId)
REFERENCES Missions (GroupId, MissionId);
要实现此SQL Server,首先需要在Missions表中对(GroupId,MissionId)执行(冗余)UNIQUE约束。其他DBMS不是那么严格,但SQL Server需要FOREIGN KEY约束才能完全匹配唯一性约束的列。
答案 1 :(得分:0)
你应该使用外键加强这一点,例如Mission.GroupId应该引用Group.GroupId。
答案 2 :(得分:0)
是否可以强制滚动分配的参考完整性,以便只选择相应组的成员(由MissionId给出)?
是。您需要使用标识关系将GroupId
一直传播到此“菱形”依赖关系的底部,类似于:
在FK1
前面注意FK2
和MissionRollAssignment.GroupId
,表示外键存在于此“菱形”依赖关系的两个“边”上。
由于单个活动任务可以在相反方向上建模为外键,在本例中为Group {GroupId, ActiveMissionNo}
,它引用Mission
主键。
这样的循环外键在不支持延迟约束的DBMS上呈现“鸡与蛋”问题(SQL Server没有)。但是,您可以将Group.ActiveMissionNo
置为NULL,因此以MATCH SIMPLE方式(SQL Server执行)强制执行外键的DBMS将忽略整个复合外键(如果其中一个字段为空值。这将允许您在插入新数据时暂时“禁用”外键并打破“鸡与蛋”循环。