可为空的外键 - 好的还是坏的做法?
Nullable foreign keys - good or bad practice?
假设我有 2 个 tables:foo 和 bar.
第三个 table 我想存储不同类型的数据,但是每一行都会引用 foo 或 bar.
如果我创建 2 个 NULL
可用外键是否正确 - foo_id 和 bar_id - 在第三个 table 中,还是违反了数据库设计原则?
基本上,我一直认为外键需要总是有一个 "parent",所以如果我尝试,例如INSERT
没有主键匹配的行(或者,在这种情况下,外键设置为 NULL
),我会得到一个错误。可空 FK-s 对我来说是新手,感觉有点不对劲。
此外,还有哪些选择?创建单独的 tables 存储单个引用是否更好?这不是在制造冗余吗?
正在链接 tables?
求助。
可为空的 FK 是 "okay"。当您尝试插入不存在的父密钥时,您仍然会收到错误消息(现在只允许 NULL
)。
备选方案是两个 link table,一个用于 foo
,一个用于 bar
。
需要考虑的事项:
Link table 允许 1:N。如果你不想这样,你可以通过 link table 上的主键强制执行。这对于 id 列解决方案不是必需的(它们始终是 1:N)。
您可以使用 link table 来避免包含大多数 NULL
值的列。但是,在您的情况下,您似乎正好有一半的值是 NULL 。可能不符合 "mostly" 的条件。这对于超过两个父 tables.
变得更有趣
您可能想要强制执行约束,即您的两列中的一列恰好是 NULL
。这可以通过使用检查约束的 id 列版本来完成。它不能用 link tables 完成(除非你可能使用触发器)。
这取决于程序的业务逻辑。如果外键字段必须有一个值,那么将它设置为 null-able 是不好的。
例如。
一本书 table 有 category_id
字段,该字段的值引用自 bookCategory
table。
图书 table 中的每条记录都必须有类别 。如果出于某种原因将其设置为 nullable 。这将导致 table 中的某些记录 category_id
为空。
该问题将显示在报告中。以下 2 个查询将 return 不同 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
我的建议是不要使用 null-able 除非你期望 value 和 no-value 。许多复杂的系统有时与一份报告和另一份报告的价值不同,通常是由此引起的。
假设我有 2 个 tables:foo 和 bar.
第三个 table 我想存储不同类型的数据,但是每一行都会引用 foo 或 bar.
如果我创建 2 个 NULL
可用外键是否正确 - foo_id 和 bar_id - 在第三个 table 中,还是违反了数据库设计原则?
基本上,我一直认为外键需要总是有一个 "parent",所以如果我尝试,例如INSERT
没有主键匹配的行(或者,在这种情况下,外键设置为 NULL
),我会得到一个错误。可空 FK-s 对我来说是新手,感觉有点不对劲。
此外,还有哪些选择?创建单独的 tables 存储单个引用是否更好?这不是在制造冗余吗?
正在链接 tables?
求助。
可为空的 FK 是 "okay"。当您尝试插入不存在的父密钥时,您仍然会收到错误消息(现在只允许 NULL
)。
备选方案是两个 link table,一个用于 foo
,一个用于 bar
。
需要考虑的事项:
Link table 允许 1:N。如果你不想这样,你可以通过 link table 上的主键强制执行。这对于 id 列解决方案不是必需的(它们始终是 1:N)。
您可以使用 link table 来避免包含大多数
NULL
值的列。但是,在您的情况下,您似乎正好有一半的值是 NULL 。可能不符合 "mostly" 的条件。这对于超过两个父 tables. 变得更有趣
您可能想要强制执行约束,即您的两列中的一列恰好是
NULL
。这可以通过使用检查约束的 id 列版本来完成。它不能用 link tables 完成(除非你可能使用触发器)。
这取决于程序的业务逻辑。如果外键字段必须有一个值,那么将它设置为 null-able 是不好的。
例如。
一本书 table 有 category_id
字段,该字段的值引用自 bookCategory
table。
图书 table 中的每条记录都必须有类别 。如果出于某种原因将其设置为 nullable 。这将导致 table 中的某些记录 category_id
为空。
该问题将显示在报告中。以下 2 个查询将 return 不同 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
我的建议是不要使用 null-able 除非你期望 value 和 no-value 。许多复杂的系统有时与一份报告和另一份报告的价值不同,通常是由此引起的。