2011-10-18 168 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人。此外,如果您认为这对您的逻辑非常重要,您可以向此表添加订单栏。