2011-10-18 216 views
0

這可能是一個比實體框架更廣泛的SQL主題,我在這兩個領域都是一個新手,但我會用實體框架來提問。實體框架多對8關係?

我想執行一個多對8的關係。我的設置是這樣的:

  • PersonGroup需要8個(唯一)人員。
  • 一個人可以在許多不同的PersonGroups中。
  • PersonGroup的順序很重要(首先需要保持第一位等)。 。
  • 給所有的人在PersonGroup和所有PersonGroups一個人在輕鬆訪問

我已經試過如下:

1)添加個人和PersonGroup之間8個1..many協會。使用此解決方案,我當然不能有超過8人每組。但是,要查找一個人所在的組,我需要在Person字段中迭代8個變量,這個變量很笨重。

2)將8個id添加到與Person匹配的PersonGroup。再一次,我可以保證每組只有8人,但沒有通過Person-> PersonGroup關聯的自動鏈接。我現在需要確保將它添加到兩個地方。

3)只是做了很多很多的關係,並在代碼中處理它。這有兩個問題:我不能保證每組只有8人,並且我不確定是否可以確保訂單保持不變。

那麼,哪個最好,或者我缺少什麼解決方案?

回答

3

以「抓」的n:m關係:

Person 
------ 
PersonId 
PRIMARY KEY (PersonId) 


PersonGroup 
----------- 
GroupId 
PRIMARY KEY (GroupId) 


Belongs 
------- 
GroupId 
PersonId 
Ordering 

PRIMARY KEY (GroupId, PersonId) 
FOREIGN KEY (GroupId) 
    REFERENCES PersonGroup (GroupId) 
FOREIGN KEY (PersonId) 
    REFERENCES Person (PersonId)    --- all normal up to here 

UNIQUE KEY (GroupId, Ordering)    --- the "catch" 
CONSTRAINT Ordering_chk      --- ensuring only up to 8 persons 
    CHECK Ordering IN (1,2,3,4,5,6,7,8)  --- per group 

你應該確保在CHECK約束是在你使用SQL引擎可用的(MySQL的例子就是誘騙用戶相信它有這樣但它只是忽略它們SQL-Server不會返回錯誤,但如果您嘗試插入一個,則在檢查列中愉快地添加NULL)。

這種方法存在限制。 Ordering字段必須是NOT NULL,因爲如果它是NULL,可以插入超過8行(其中包含NULL)(SQL-Server除外,只允許最多9行,其中8個包含值,另一個包含NULL)。)

爲了確保最高的8行和NULL值在Ordering的,你可以讓像MSDN site, CHECK Constraints描述的一個較爲複雜的約束(如果您的RDBMS有這樣的功能),但我不上的表現都肯定這樣的野獸:

CREATE FUNCTION CheckMax8PersonPerGroup() 
RETURNS int 
AS 
BEGIN 
    DECLARE @retval int 
    SELECT @retval = CASE WHEN EXISTS 
           (SELECT * 
           FROM Belongs 
           GROUP BY GroupId 
           HAVING COUNT(*) > 8 
          ) 
         THEN 0 
         ELSE 1 
        END 
    RETURN @retval 
END; 
GO 
ALTER TABLE Belongs 
ADD CONSTRAINT Ordering_chk 
     CHECK (CheckMax8PersonPerGroup() = 1); 
GO 

約束可替代地創建爲FOREIGN KEY到參考表8點的行。 (如果你使用MySQL,這是爲具有CHECK同等的唯一途徑。)


的變化是使用了(GroupId, Ordering)作爲主鍵,而不是對(GroupId, PersonId)組合的任何約束。這將允許PersonGroup(但仍然高達8)中具有多個職位。

3

多對多對我來說似乎沒問題。通過實施觸發器,您可以輕鬆確保每個組不超過8人。此外,如果您認爲這對您的邏輯非常重要,您可以向此表添加訂單欄。