可空的外键 - 好的或坏的做法?

时间:2015-01-12 00:46:03

标签: mysql foreign-keys

我们假设我有2个表: foo bar

在第三个表格中,我想存储不同类型的数据,但每行都会引用 foo bar

如果我在第三个表中创建了2个NULL能够使用的外键 - foo_id bar_id ,还是数据库设计原则?

基本上,我一直认为外键总是需要一个父母"所以如果我试图例如INSERT没有匹配主键的行(或者,在这种情况下,外键设置为NULL),我将收到错误。 Nullable FK-s对我来说是新手,他们感觉有点不对劲。

另外,有哪些替代方案?创建存储单引用的单独表是否更好?这不是创造冗余吗?

链接表?

帮助。

2 个答案:

答案 0 :(得分:3)

可以为空的FK“好”。当您尝试插入不存在的父密钥时,您仍会收到错误(现在只允许NULL)。

另一种选择是两个链接表,一个用于foo,另一个用于bar

需要考虑的事项:

  • 链接表允许1:N。如果您不想这样,可以通过链接表上的主键强制执行。这对于id列解决方案来说不是必需的(它们总是1:N)。

  • 您可以使用链接表避免使用大多数NULL值的列。但是,在您的情况下,似乎您只有一半的值为NULL。可能不符合“大部分”的条件。对于两个以上的父表,这会变得更有趣。

  • 您可能希望强制执行两列中只有一列为NULL的约束。这可以使用检查约束使用id列版本来完成。它不能用链接表完成(除非您使用触发器)。

答案 1 :(得分:0)

取决于程序的业务逻辑。如果外键字段必须有值,则将其设置为null是不好的。

例如,

。 书表具有category_id字段,其值是bookCategory表的引用。

书表中的每条记录都必须有类别。如果由于某种原因你将其设置为可空。这将导致书表中的某些记录category_id为空。

问题将显示在报告中。以下2个查询将返回不同的total_book

select count(*) as total_book from book;
select 
   count(*) as total_book 
from 
   book 
   inner join bookCategory 
      on book.category_id = category.id

除非你期望价值和无价值,否则我的建议是不能使用无效。很多复杂的系统,有时候有一个报告和另一个报告的价值不同,通常是由此引起的。