担心使用外键删除行时的递归

时间:2011-04-11 12:17:35

标签: sql sql-server sql-server-2005 tsql foreign-keys

我正在尝试清理一个包含大量垃圾记录的数据库,

它是一个关系结构,并且有外键将所有内容链接在一起,我有一个删除命令设置:

DELETE FROM Members
WHERE (CurrentClass = 339) AND (YEAR(LastSessionDate) < 2011)

DB结构如下所示:

Members
-----------------------------------------------------------------------
Id ¦ FirstName ¦ LastName ¦ JoiningClass ¦ CurrentClass ¦ CurrentScheme
-----------------------------------------------------------------------
0  ¦ Fakey     ¦ McFake   ¦ 123          ¦ 999          ¦ 2
-----------------------------------------------------------------------
1  ¦ Fakette   ¦ McFake   ¦ 123          ¦ 998          ¦ 1
-----------------------------------------------------------------------

上表在字段Classes上引用了表PricingJoiningClass, CurrentClass and CurrentScheme,然后这些表引用了其中包含字段的其他表,所以基本上所有内容都引用了所有内容。

我想删除符合我的标准的上述记录,但我收到外键警告。

我考虑过添加:

ON DELETE CASCADE

但是我担心,因为所有内容都会引用其他所有数据库数据。

即。如果我删除上面的记录0,它将删除类123999,这将删除其所有引用。

这种情况发生了还是我应该更清楚?

2 个答案:

答案 0 :(得分:2)

如果你说的“一切都引用一切”,那么如果没有对模式进行一些严肃的(阅读:耗时,烦人的)分析,很难说清楚会发生什么。使用第三方工具也是如此 - 你永远不会100%确定他们会做什么,删除记录不是你想要在生产数据库上冒险的东西。

相反,您应该创建数据库的另一个副本(备份您的架构,然后从另一台服务器上的备份重新创建它),添加级联触发器并查看会发生什么。

答案 1 :(得分:1)

我猜想JoiningClass和CurrentClass是Members记录的父级。因此它们不会被删除。当然,您收到的消息表明它是一个具有子记录的不同表,导致删除失败。现在只有你可以知道这是否是正确的行为,即如果有子记录你不希望删除记录,或者你想通过级联删除控制所有删除。我个人从不使用级联删除,因为它可能会导致性能问题,如果它们是很多子记录(在这种情况下最好先批量删除它们,然后是父表)或者你有上面的情况你不在任何情况下想要如果孩子存在则删除。例如,如果客户有过去需要正确财务报告的订单,则不希望删除该客户,在这种情况下,您将使客户处于非活动状态而不是删除。

在尝试使用级联删除进行删除之前,请确保您有当前备份。