2012-04-20 66 views
0

我有2个表UserGroup。 我有一个表Attributes共享由用户和组的列:SQL 2个父表的外键问题

  • attributeName
  • AttributeValue
  • ObjectID

ObjectID指向用户的主键或组的主键。 我已经添加了一个外部约束Cascade on Delete为了删除用户或组时自动删除属性。

现在的问题是,当我插入用户的属性,我有一个外键约束,因为该组不存在。

我该如何继续?

+0

我认为你应该考虑两个属性表。一个用于用户,另一个用于组。 – 2012-04-20 21:52:48

+0

或用父表上的触发器替换外键和约束来捕获删除? – CloudAnywhere 2012-04-20 21:57:40

+0

我不会。 FK的主要目的不是级联删除。它确保您不会为不存在的用户/组添加属性。在UserId和GroupId的Attributes中具有相同的字段是一个坏主意。而不是两个表,你可以在属性中有两列,但正如我所说,我会去两个表。 – 2012-04-20 22:08:09

回答

2

你已经基本上3个选项:

  1. 保持当前的设计,而是采用UserIDGroupID更换Attribute.ObjectID,另附FK他们每个人(一个对Group,另一个朝向User),并允许要么是NULL。你还想要一个CHECK约束来确保不是都是NULL。

    enter image description here

  2. 拆分AttributeUserAttributeGroupAttribute,从而分隔每个外键进入自己的表。

    enter image description here

  3. 使用继承,像这样:

    enter image description here

解决方案(1)高度依赖于你的DBMS如何处理UNIQUE null和两(1) (2)允许相同的AttributeName用于两个不同的属性,一个用于用户,另一个用于组。

0

我想你应该让NULL值这个外键字段ObjectId,这样就可以与ObjectId = NULL,不是引用任何用户或组插入任何行。

为了更好的设计,您应该删除这个ObjectId列,将新列AttributeId添加到UserGroup两个表中。

0

正如你发现你不能有一列作为外键到两个不同的表。如果用户不存在具有相同ID的组,则不能为其添加属性。当然,您可以不知道该属性是否适用于用户或组。

从评论你也提到了用户和组之间的m:m关系,所以我会建议如下。

create table [User] 
(
    UserID int identity primary key, 
    Name varchar(50) not null 
) 

go 

create table [Group] 
(
    GroupID int identity primary key, 
    Name varchar(50) not null 
) 

go 

create table UserGroup 
(
    UserID int not null references [User](UserID), 
    GroupID int not null references [Group](GroupID), 
    primary key (UserID, GroupID) 
) 

go 

create table UserAttribute 
(
    UserAttributeID int identity primary key, 
    Name varchar(50) not null, 
    Value varchar(50) not null, 
    UserID int not null references [User](UserID) on delete cascade 
) 

go 

create table GroupAttribute 
(
    GroupAttributeID int identity primary key, 
    Name varchar(50) not null, 
    Value varchar(50) not null, 
    GroupID int not null references [Group](GroupID) on delete cascade 
) 

注意:属性表的使用应该针对您以前不知道的属性。所有你知道的东西都是属性,应该是实际表中的字段。保留使用客户定义属性的属性。

+0

非常感谢Mikael。 – CloudAnywhere 2012-04-23 20:19:14