外键是否总是需要约束?

时间:2016-07-25 07:22:59

标签: mysql database

我知道这是一个奇怪的问题,因为我总是被教导使用外键约束。但是,我发现在删除引用时必须保留外键参考值以用于历史目的的情况。

这是一个任务管理系统,任务事件引用包含重复规则的父任务。可以删除此父任务,但事件本身必须与不存在的父ID保持一致。如果找不到父任务,系统只会返回错误 - 例如"父任务不再存在。"无法在级联上将父ID设置为null的原因是因为它在事件中的其他位置用作标识键。

另一个例子:从播放列表中删除的YouTube视频怎么样?类似的情况吧?它在播放列表中被引用,但视频不存在,因此它会在播放列表中返回错误。

我根本没有完全定义外键而只是简单地将parent_id引用列创建为普通列?我只是想确定当遇到一个表引用另一个表的情况时如何正常处理,但前者不受后者存在的限制。

2 个答案:

答案 0 :(得分:4)

有一个约束只是一个技术帮助,可以强制执行为数据库定义的语义,即"此列包含的数字不仅是INTEGER(32),还包含其他一些记录的标识符表&#34 ;.因此,他们并非绝对必要,但它:

  • 明确了该字段的意图(自我文档)
  • 保持您的数据"清洁"通过防止插入不正确的数据
  • 为数据库引擎提供有关表的内容的提示,这可能使数据库更有效地执行。

那说,"适当"完成你所描述的内容的方法不是首先实际删除父记录。而是将父项标记为已删除。由于您出于历史目的而保留记录,因此您肯定希望能够知道父母曾经是什么,即使它已经不再有效或有效。

第二个选项是创建一个删除的虚拟"父记录"参考。每当删除父项时,都会更新剩余的引用以指向虚拟记录。至少你不会依赖错误来实现预期和有效的行为。

最后,我认为你没有理由不能将外键设置为NULL。听起来你正在使用外键作为相关记录的主键的一部分("正被用作...作为识别键")。你几乎肯定不应该这样做,如果这是问题的根本原因,首先要改变它。

答案 1 :(得分:0)

  

我根本就不定义外键而只是简单地创建   parent_id引用列为普通列?

是。至少这是我了解的方式,以及我们如何处理这些工作。

然后,您可能希望在参考列上设置索引。