2013-11-27 60 views
0

我正在設計一個數據庫,但無法弄清楚如何對參照完整性建模。對錶部分的參照完整性

我有以下表

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 
) 

每個任務都會有一些任務/相應組的所有成員。將有幾個任務與每個組相關聯,但每個組只有一個任務在給定時間處於活動狀態。

我的問題是:

是否有可能執行爲卷分配referenciay完整性,使得只有成員的相應組(由MissionId給出)的 被選擇?我知道我可以從GUI過濾這個,但是如果我可以在MissionRollAssignments中創建一個FK約束到GroupMembers,同時考慮Mission中指定的GroupId,我會感覺更舒適。

第二個問題是,如果你們認爲這是模擬我的域的好方法,或者我應該嘗試不同的方法。

在此先感謝您的幫助。

最好的問候,
AWER

回答

2

你可以把的GroupId到MissionRollAssignments然後添加兩個約束如下。其他DBMS並不那麼嚴格,但SQL Server需要一個FOREIGN KEY約束來完全匹配唯一性約束的列。

+0

我一直在試驗這個,它實際上工作正常!謝謝你的幫助。你能否給我一點解釋,說明這是如何完成我想要的? –

+0

嗨sqlvogel。我想我現在明白了,但現在我認爲,通過在MissionRoleAssignments中引入GroupId,現在數據庫不再處於3NF中。我對麼?這是一個問題嗎? –

+0

由於MissionRollAssignments中的MissionId-> GroupId非關鍵依賴關係,您是對的。然而,這個約束仍然被FK約束有效地執行,所以在那裏沒有完整性的損失。在該表中沒有GroupId的替代方案會使執行您所說的業務規則更加困難。這種情況通常出現在SQL中。 SQL對完整性約束的支持非常有限,執行某些業務規則的唯一方法是反規範化。您必須決定在數據庫中執行規則有多大價值。 – sqlvogel

0

你應該使用外鍵來強化這一點,例如Mission.GroupId應參照Group.GroupId。在任務表

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,首先需要一個(冗餘)唯一約束(GroupId的,MissionId):

+0

要對組成員強制分配,您應該更改MissionRollAssignments表以包含GroupMemberId(新列)而不是MemberId。 – SAS

0

是否有可能強制參與卷屬性的引用完整性,以便只選擇相應組的成員(由MissionId給出)?

是的。您需要使用標識關係到GroupId一路向下傳播這種「菱形」依賴的底部,與此類似:在MissionRollAssignment.GroupId

enter image description here

FK1FK2,表明外鍵存在於這種「菱形」依賴的兩個「邊」。


作爲單一活性任務可被建模爲在相反的方向作爲Group {GroupId, ActiveMissionNo}外鍵,在這種情況下引用Mission主鍵。

這樣的循環外鍵在不支持延遲約束的DBMS上呈現「雞與蛋」問題(SQL Server不支持)。但是,您可以將Group.ActiveMissionNo設置爲NULL,因此以MATCH SIMPLE方式(即SQL Server所用的方式)強制執行外鍵的DBMS將忽略整個組合外鍵(如果其中一個字段爲NULL)。這將允許您暫時「禁用」外鍵,並在插入新數據時打破「雞與雞蛋」循環。