我有2個表User
和Group
。 我有一個表Attributes
共享由用戶和組的列:SQL 2個父表的外鍵問題
attributeName
。AttributeValue
。ObjectID
。
ObjectID
指向用戶的主鍵或組的主鍵。 我已經添加了一個外部約束Cascade on Delete
爲了刪除用戶或組時自動刪除屬性。
現在的問題是,當我插入用戶的屬性,我有一個外鍵約束,因爲該組不存在。
我該如何繼續?
我有2個表User
和Group
。 我有一個表Attributes
共享由用戶和組的列:SQL 2個父表的外鍵問題
attributeName
。AttributeValue
。ObjectID
。ObjectID
指向用戶的主鍵或組的主鍵。 我已經添加了一個外部約束Cascade on Delete
爲了刪除用戶或組時自動刪除屬性。
現在的問題是,當我插入用戶的屬性,我有一個外鍵約束,因爲該組不存在。
我該如何繼續?
你已經基本上3個選項:
保持當前的設計,而是採用UserID
和GroupID
更換Attribute.ObjectID
,另附FK他們每個人(一個對Group
,另一個朝向User
),並允許要麼是NULL。你還想要一個CHECK約束來確保不是都是NULL。
拆分Attribute
表UserAttribute
和GroupAttribute
,從而分隔每個外鍵進入自己的表。
使用繼承,像這樣:
解決方案(1)高度依賴於你的DBMS如何處理UNIQUE null和兩(1) (2)允許相同的AttributeName
用於兩個不同的屬性,一個用於用戶,另一個用於組。
我想你應該讓NULL
值這個外鍵字段ObjectId
,這樣就可以與ObjectId
= NULL,不是引用任何用戶或組插入任何行。
爲了更好的設計,您應該刪除這個ObjectId
列,將新列AttributeId
添加到User
和Group
兩個表中。
正如你發現你不能有一列作爲外鍵到兩個不同的表。如果用戶不存在具有相同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
)
注意:屬性表的使用應該針對您以前不知道的屬性。所有你知道的東西都是屬性,應該是實際表中的字段。保留使用客戶定義屬性的屬性。
非常感謝Mikael。 – CloudAnywhere 2012-04-23 20:19:14
我認爲你應該考慮兩個屬性表。一個用於用戶,另一個用於組。 – 2012-04-20 21:52:48
或用父表上的觸發器替換外鍵和約束來捕獲刪除? – CloudAnywhere 2012-04-20 21:57:40
我不會。 FK的主要目的不是級聯刪除。它確保您不會爲不存在的用戶/組添加屬性。在UserId和GroupId的Attributes中具有相同的字段是一個壞主意。而不是兩個表,你可以在屬性中有兩列,但正如我所說,我會去兩個表。 – 2012-04-20 22:08:09