你如何处理消除可能是FK的数据库记录?

时间:2011-05-21 18:32:25

标签: sql-server tsql entity-framework-4

想象一下这个设置:

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?

在现实世界中,你是如何处理这种情况的?

4 个答案:

答案 0 :(得分:2)

在许多情况下,这是正确的做法 - 这就是ON DELETE CASCADE存在的原因。

这意味着对于已删除的行,另一个表中定义为该行上的外键的任何行也将被删除。

您需要问的问题是,用户真正想要的是什么?在应用程序域中执行此类删除是否有意义?如果他们删除观察类型,请询问您的用户他们期望发生什么 - 他们认为现有观察结果会发生什么。

有时,最好使用软删除(在状态字段中标记具有删除状态的行),这样您就可以恢复/取消删除。这不是没有its share of problems

答案 1 :(得分:2)

为外键添加级联删除?另外,你真的想从你的数据库中删除吗?为什么不把它们标记为无效?

答案 2 :(得分:0)

虽然它存在且有用,但我不建议设置级联删除。但我确实同意,软删除可能是一件好事。

但是,根据您的需要,为什么不创建一个

的过程
  1. 删除相应的观察记录
  2. 删除ObservationType
  3. 日志(ActivityLog?)已删除的内容和原因(注释)。不需要存储整套已删除的数据,但只需要足够的合规性(又称SOX)。谁,什么,何时。

答案 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是一个容易出错的解决方案。