这个问题在标题中!
我用来存储我的(生产)网站数据的数据库包含很多ON DELETE CASCADE
.
我只是想知道这是否是一件好事,或者它是否是手动编码所有删除的更好方法。
一方面,它不是很明确:删除是通过魔法实现的,另一方面,它使开发更容易:我不必将数据库的整个模式都牢记在心。
我认为保持参照完整性是一件好事。您最不想要的是数据库中的孤立行。
有关不使用引用完整性时要考虑的事项,请参阅 MySQL 文档:
MySQL 让数据库开发人员可以选择使用哪种方法。如果您不需要外键并希望避免与强制引用完整性相关的开销,则可以选择另一个存储引擎,例如 MyISAM。(例如,MyISAM 存储引擎为只执行 INSERT 和 SELECT 操作的应用程序提供了非常快的性能。在这种情况下,表中间没有孔,插入可以与检索同时执行。参见第 8.10.3 节, “并发插入”。)
如果您选择不利用参照完整性检查,请记住以下注意事项:
在没有服务器端外键关系检查的情况下,应用程序本身必须处理关系问题。例如,必须注意以正确的顺序将行插入表中,并避免创建孤立的子记录。它还必须能够从多记录插入操作中间发生的错误中恢复。
如果 ON DELETE 是应用程序需要的唯一引用完整性功能,则可以通过使用多表 DELETE 语句通过单个语句从多个表中删除行来实现与 MySQL Server 4.0 类似的效果。请参见第 13.2.2 节,“DELETE 语法”。
缺少 ON DELETE 的一种解决方法是,当您从具有外键的表中删除记录时,将适当的 DELETE 语句添加到您的应用程序中。在实践中,这通常与使用外键一样快,并且更便携。
请注意,使用外键有时会导致问题:
外键支持解决了许多引用完整性问题,但仍然需要仔细设计键关系以避免循环规则或级联删除的错误组合。
DBA 创建关系拓扑结构使得从备份中恢复单个表变得困难的情况并不少见。(MySQL 通过使您能够在重新加载依赖于其他表的表时临时禁用外键检查来缓解此困难。请参阅第 14.3.5.4 节,“外键约束”。从 MySQL 4.1.1 开始,mysqldump 生成的转储文件利用重新加载时会自动关闭此功能。)
来源:http ://dev.mysql.com/doc/refman/5.5/en/ansi-diff-foreign-keys.html
级联删除是您使用的绝佳工具,前提是您确保仅在非常有意义的情况下使用它们。
您选择使用级联删除的主要情况是当您有一个表,该表对由另一个表中的一个(并且只有一个)行“拥有”的实体进行建模。例如,如果您有一个模拟人员的表格和一个模拟电话号码的表格。在这里,您的电话号码表将具有您的人员表的外键。现在,如果您决定不再希望您的应用程序跟踪某人——比如说“Douglas”——那么您也不想再跟踪 Douglas 的电话号码是完全有道理的。让一个电话号码在你的数据库中浮动并且不知道它是谁,这是没有意义的。
但同时,当您想从“人员”表中删除一个人时,您不想先费力地检查您是否有该人的电话号码并将其删除。当您可以将删除一个人时,他们的电话号码也可以全部删除的规则编码到数据库结构中时,为什么要这样做呢?这就是级联删除将为您做的事情。只要确保你知道你有什么级联删除,并且它们都是有意义的。
注意。如果使用触发器,则需要更加小心。MySQL 不会触发级联删除的触发器。