删除时重叠外键和级联

时间:2015-01-26 14:10:59

标签: sql sql-server sql-server-2008 foreign-keys

假设我有4张桌子,A,B,C,D。

A有一个ID的主键 B有一个主键(ID,A.ID),其中A.ID是CASCADE ON DELETE的外键 C有一个主键(ID,A.ID),其中A.ID是CASCADE ON DELETE的外键 D的主键为(ID,A.ID,B.ID,C.ID),其中(A.ID,B.ID)和(A.ID,C.ID)为外键。

对于D的两个外键,有没有办法使用CASCADE ON DELETE?尝试级联这两个外键给我一个“多级联路径”错误,两个外键级联删除A.ID,但我需要删除行中的行B.ID或C.ID被删除。

编辑:

表DeviceTypes,DeviceInstances,DeviceDataElements,DeviceDataRecords

DeviceTypes的主键为ID。

DeviceInstances的主键为(ID,DeviceTypes.ID),DeviceTypes.ID为CASCADE ON DELETE的外键。

DeviceDataElements的主键为(ID,DeviceTypes.ID),DeviceTypes.ID为CASCADE ON DELETE的外键。

D的主键为(ID,Devices.ID,DeviceElements.ID,DeviceInstances.ID),其中(DeviceTypes.ID,DeviceElements.ID)和(DeviceTypes.ID,DeviceInstances.ID)为外键。< / p>

即。 DeviceRecord包含特定DeviceInstance的DeviceDataElement的数据点。

1 个答案:

答案 0 :(得分:0)

我只能猜测主题区域,但对于我来说,DeviceTypes.ID不应该是DeviceInstances和DeviceDataElements中主键的一部分。例如,此列不需要在DeviceInstances中唯一标识记录。 DeviceInstance不可能具有相同的DeviceInstanceID但不同的DeviceTypeID。

此外,我不认为应该级联DeviceTypes中的删除。从DeviceType中删除并不常见(且危险)操作。如果必须实现它,请编写存储过程,并以正确的顺序从相关表中删除(DeviceDataRecords,DeviceDataElements,DeviceInstances,DeviceTypes)。另一种实现方法是将DeviceType标记为已删除,而不是物理删除。在这种情况下,您永远不会丢失数据。

同样,从DeviceDataElements中删除也会受到质疑。我不认为DataElements会因某些类型而改变。

在此设计中,您必须从应用程序端控制DeviceRecord仅包含Instance类型允许的DataElements。处理这种情况是非常常见和自然的方式(在应用程序或业务逻辑方面这样做)。从逻辑的角度来看,DeviceDataRecords包含一些实例具有一些DataElement(某些值)的事实。检查此表中的类型是不自然的。将这些检查委派给SQL Server并不是一个好主意。如果服务器端只有可用选项,您可以考虑此任务的触发器,因此在INSERT in Records中您可以检查此规则(这也不是一个好选项)。

我在申请的主题方面可能出错了,所以请纠正我或添加新信息。

CREATE TABLE DeviceTypes(DeviceTypeID int not null identity primary key);
go

CREATE TABLE DeviceInstances (DeviceInstanceID int not null identity primary key, DeviceTypeID int not null)
ALTER TABLE DeviceInstances ADD CONSTRAINT FK_DeviceInstances_DeviceTypes FOREIGN KEY (DeviceTypeID) REFERENCES DeviceTypes(DeviceTypeID) 
go

CREATE TABLE DeviceDataElements (DeviceDataElementID int not null identity primary key, DeviceTypeID int not null)
ALTER TABLE DeviceDataElements ADD CONSTRAINT FK_DeviceDataElements_DeviceTypes FOREIGN KEY (DeviceTypeID) REFERENCES DeviceTypes(DeviceTypeID) 
go

CREATE TABLE DeviceDataRecords (RecordID int not null identity primary key, DeviceInstanceID int not null, DeviceDataElementID int not null)
ALTER TABLE DeviceDataRecords ADD CONSTRAINT FK_DeviceDataRecords_DeviceInstances FOREIGN KEY (DeviceInstanceID) REFERENCES DeviceInstances(DeviceInstanceID) on delete cascade
ALTER TABLE DeviceDataRecords ADD CONSTRAINT FK_DeviceDataRecords_DeviceDataElements FOREIGN KEY (DeviceDataElementID) REFERENCES DeviceDataElements(DeviceDataElementID) on delete cascade