想象一下这个设置:
create table ObservationType
(
ObservationTypeId int primary key identity(1,1),
Name nvarchar(32) not null
)
create table Observation
(
ObservationId int primary key identity(1,1),
ObservationTypeId int foreign key references ObservationType(ObservationTypeId),
Title nvarchar(32) not null,
Description nvarchar(1024) not null,
StudentId int foreign key references Student(StudentId)
)
create table Student
(
foo bar
)
现在想象这里充满了数据,它运行正常。当用户想要删除观察类型时,您如何处理?您是否自动删除任何具有该特定类型的观察为FK?
在现实世界中,你是如何处理这种情况的?
答案 0 :(得分:2)
在许多情况下,这是正确的做法 - 这就是ON DELETE CASCADE
存在的原因。
这意味着对于已删除的行,另一个表中定义为该行上的外键的任何行也将被删除。
您需要问的问题是,用户真正想要的是什么?在应用程序域中执行此类删除是否有意义?如果他们删除观察类型,请询问您的用户他们期望发生什么 - 他们认为现有观察结果会发生什么。
有时,最好使用软删除(在状态字段中标记具有删除状态的行),这样您就可以恢复/取消删除。这不是没有its share of problems。
答案 1 :(得分:2)
为外键添加级联删除?另外,你真的想从你的数据库中删除吗?为什么不把它们标记为无效?
答案 2 :(得分:0)
虽然它存在且有用,但我不建议设置级联删除。但我确实同意,软删除可能是一件好事。
但是,根据您的需要,为什么不创建一个
的过程答案 3 :(得分:0)
如果可能,我更喜欢使用'soft'删除。这意味着在表上删除了位列。 因此,当您删除时,您实际上会在表上运行update语句以将Deleted设置为1。
但是,如果我想删除行肯定,我会使用显式删除语句,而不是ON DELETE CASCADE
外键。
delete Observation
where ObservationTypeId = 1
delete ObservationType
where ObservationTypeId = 1
我尽量避免使用隐式ON DELETE CASCADE
,因为它可能导致隐藏的危险意外删除。
如果所有数据库都是基于级联删除外键构建的,那么错误的人可以通过对所有其他表中引用的一个表运行delete来删除整个数据库的内容。所以简而言之,我发现ON DELETE CASCADE
是一个容易出错的解决方案。