【发布时间】:2009-07-21 13:30:56
【问题描述】:
我们有一个通常具有这种结构的数据库:
Master Record Table
id (pk)
MasterRecordId <-- constrained to be unique
儿童/兄弟姐妹(第二代,如果你愿意的话):
Table1
( table1ID (pk),
MasterRecordID (fk))
Table2
( Table2ID(pk),
MasterRecordID (fk))
孙子(第三代):
Table3
( Table3ID (pk)
Table1ID (fk))
Table4
(Table4ID (pk)
Table1ID (fk))
Table5
(Table5ID (pk)
Table2ID (fk))
并非第二代的每张桌子都有孩子。应用程序中有限制删除功能(您可以删除任何单独的记录,但在许多情况下 FK 会阻止删除;删除功能很糟糕,并且不会优雅地失效)。
我的任务是调查处理删除的最佳方法。为了清除从大师到孙子的整个记录,后端是唯一的方法。这让 The Powers That Be 很高兴。但是,你知道,用户撒谎,所以事实证明我们可能需要改变这一点(这样我就不必偶尔充当官方记录删除者,而且因为有某些类型的 Gen 2 记录用户删除 经常。
级联删除是第一个选项,因为 TPTB 希望这不需要在应用程序的新版本上工作。因为那是在那次特定会议结束时从我老板的嘴里蹦出来的话。我的 Gen 2 -> Gen 3 级联都运行良好(这涵盖了最常见的用例/故事/你有什么)。然后我更新了所有 Master -> Gen 2 Foreign Keys 以在删除时级联。 希望这将允许删除主记录,并且所有其他孩子和孙子都会使用它。不好;当我尝试删除主记录时,我收到一条违反第一个 Master -> Gen 2 FK 的错误消息。我已经仔细检查过; FK 设置为在删除时级联。
对于具有 1 级以上表关系的级联删除,我有什么不明白的地方?我正在尽可能多地阅读(在时间允许的情况下),但我还没有发现能够带领我走出这段黑暗时期的知识。级联是错误的方法吗?
其次,在我看来,还有另外两个选择:
在应用程序中执行所有删除操作。不是首选,但如果它是唯一的选择,那就是唯一的选择。我知道有人认为这是最好的选择,但 TPTB 对最好的看法与我不同(虽然他们都疯了,但他们签了支票)。
通过触发器处理删除?我不清楚外键是否会妨碍这一点,但我想到这可能是一种选择。
好吧,还有:
- 执行 Gen 2 -> Gen 3 级联。然后少数拥有删除权限的人只需按照惯例进行完全删除(即:单独删除所有第 2 代记录,然后删除主记录)。或者,我将被困为官方记录删除者。
【问题讨论】:
标签: sql sql-server-2005 cascading-deletes