2012-04-20 90 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