我们假设我有2个表: foo 和 bar 。
在第三个表格中,我想存储不同类型的数据,但每行都会引用 foo 或 bar 。
如果我在第三个表中创建了2个NULL
能够使用的外键 - foo_id 和 bar_id ,还是数据库设计原则?
基本上,我一直认为外键总是需要一个父母"所以如果我试图例如INSERT
没有匹配主键的行(或者,在这种情况下,外键设置为NULL
),我将收到错误。 Nullable FK-s对我来说是新手,他们感觉有点不对劲。
另外,有哪些替代方案?创建存储单引用的单独表是否更好?这不是创造冗余吗?
链接表?
帮助。
答案 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
除非你期望价值和无价值,否则我的建议是不能使用无效。很多复杂的系统,有时候有一个报告和另一个报告的价值不同,通常是由此引起的。