我的(删节)架构有(或者更确切地说,需要)以下表格和关系:
Clients (ID INT PRIMARY KEY)
Files (
ID INT PRIMARY KEY,
Client INT REFERENCES Clients(ID) ON DELETE CASCADE)
Interfaces (
ID INT PRIMARY KEY,
Client INT REFERENCES Clients(ID) ON DELETE CASCADE)
Files_Interfaces (
"File" INT REFERENCES Files(ID) ON DELETE CASCADE,
Interface INT REFERENCES Interfaces(ID) ON DELETE CASCADE)
从这个架构中可以看出,客户端可以有多个文件和多个接口。接口和文件之间存在多对多关系(因此联结表Files_Interfaces
),唯一的层次关系是客户端(从Clients
到Files
之间存在一对多的关系Interfaces
和Files_Interfaces
)。
我需要Files
和Interfaces
以及Files_Interfaces
之间的这些约束,这样,如果删除文件或界面,所有相关的关联都会被销毁。
问题是,SQL Server 2005不会让我拥有这个架构。当我尝试使用这些约束创建Files_Interfaces时,我收到以下错误:
引入FOREIGN KEY约束 'FK__Files_Int__Inter__3D2915A8'开启 表'Files_Interfaces'可能会导致 循环或多个级联路径。 指定ON DELETE NO ACTION或ON 更新无动作,或修改其他动作 FOREIGN KEY约束。
是什么给出的?是因为如果我删除了一个客户端,那么这两个文件和接口都会被删除,那么{{1}}个记录有两个很好的理由消失吗?如果是这样,为什么这是一件坏事?
我可以以某种方式防止此错误吗?
答案 0 :(得分:5)
虽然理论上多个级联路径(甚至是循环)没有任何问题,但实施它们可能很难。
就像现在一样,SQL Server
要求级联图应该是树而不是有向无环(甚至更糟,循环)图:
由单个
DELETE
或UPDATE
触发的一系列级联引用操作必须形成一个不包含循环引用的树。在DELETE
或UPDATE
生成的所有级联参照操作的列表中,任何表都不会出现多次。此外,级联引用操作树不得包含任何指定表的多个路径。树的任何分支在遇到已指定NO ACTION
的表或默认值时都会结束。
由于实现限制,SQL Server
不会将级联删除优化为单个基于集合的操作,而是将树拆分为一系列单独的连接。如果是A -> B -> C
,则DELETE A
不是DELETE A JOIN B JOIN C
,而是DELETE A JOIN B OUTPUT B_temp
,后跟DELETE B_temp JOIN C
。
如果有多个级联路径,则会导致多个B_temp
。