Answers:
我通常对通过触发器或进行的级联删除(以及其他可能删除/损坏数据的自动操作)保持警惕ON <something> CASCADE
。这样的设施非常强大,但也有潜在危险。
- 那么,级联删除此处是否是正确的选择?
它肯定会满足您的要求:删除父记录时删除相关记录,而无需实现任何其他逻辑来确保先删除子项,从而使代码更简洁。所有操作都将被包装在一个隐式事务中,因此,如果某个操作阻止了子操作,则该操作将删除整个操作,从而保持引用完整性,而无需或只需很少的编码工作。
确保对级联删除和其他“幕后”操作的使用进行了详细记录,以便系统的未来维护者充分意识到这一点。
- 级联时应该不使用?
如果您像我一样偏执,就不要使用它!要考虑的一个关键点是当前或将来可能在您的代码/数据库上工作的其他开发人员(因此,上面的注释中记录了任何“隐藏”行为)。
在我的经验中,经验不足的人经常使用DELETE
然后重新INSERT
排列以更新行,特别是当他们真正想要的是MERGE
/ UPSERT
操作时(更新现有行并创建新行,其中不存在具有给定键的行)并且DBMS不支持合并/向上更新(或者他们不知道它的支持)。如果没有级联操作,这是绝对安全的(或者,如果它威胁到数据完整性,则将出错),但是如果有人对引用FK具有的父表中的行执行此操作ON DELETE CASCADE
设置后,相关数据将由于初始删除而被删除,而不是被替换-因此数据将丢失(不是即使删除和随后的插入包装在显式事务中,级联也会通过删除操作发生-它不会等待以查看事务是否在后续语句中替换了父表中的行),并且级联可以通过其他关系船继续进行(例如:删除高级主管,其级联被删除,其团队级联被删除,所有这些人的所有跟踪记录都会被级联删除...)。如果不启用级联,您只会在这里看到错误,而不会无声地丢失数据。
我想答案取决于您的情况是否有意义,这取决于。对于您的情况,如果“子”表中的行对应的“主”行消失了,是否有意义?如果没有父表,子表中的数据将毫无意义吗?如果是这样,则级联删除将强制引用完整性。您可能希望将子行保留为记录,作为过去活动的存档(尽管您可能为此目的将这些行写到另一个表中)。
我用来说明这一点的一个例子是医生/病人的关系。一位医生可以有很多病人。患者只有医生才能成为患者。如果医生去了(放弃了练习),那么其余的病人一定会发生什么。一种可能性是它们被清除了。另一个是默认值替换了文档引用,或者可以将它们从主表中删除并放置在其他位置。或者,不进行任何活动,患者保持原样,保持原样,就像医生仍然在场一样。这取决于您想做什么。
从个人经验中,仔细考虑数据库的设计。这周,我不得不在一张指向无处可寻的表格中清理孤儿记录,这实际上占用了空间。
使用级联删除是个人喜好问题,例如是否用复数名称命名表格(客户与客户)。
我希望永远不要使用级联删除。一些数据库设计完全避免删除。当磁盘空间如此便宜时,很少有理由从数据库中删除数据。一些数据库设计将附加字段设置为“ IsDeleted”,而不是物理删除数据。
如果您必须删除数据,则可以使用存储过程进行管理,以提高透明度和控制力。您的应用程序可以执行一个存储过程,该存储过程将从子级然后从父级删除。您不知道业务需求将如何随着时间而变化,因此sp将为您带来更多的多功能性。那是我的2分。