Customers
customer_id
Orders
order_id
customer_id fk
如果我有两个表并在Orders表中的customer_id上定义了一个外键,通过允许它为null,我说我可以订购一个没有客户关联的订单。因此,可以为空的外键的概念似乎与外键的目的不一致,即强制执行此约束。
是否有一个简单的例子说明需要一个可以为空的外键?或支持允许他们的论点?
答案 0 :(得分:48)
想象一个包含团队TODO的表。如果尚未将TODO分配给团队成员,则其user_id
为NULL
。如果它不是NULL
,则它是users
表的外键。
答案 1 :(得分:16)
不,可以为空的外键永远不是必需的。
您始终可以规范化可选的1-many关系。举个例子,你可能有以下表格:
Customers: customer_id, ...
Orders: order_id, ...
OrdersCustomers: order_id, customer_id
UNIQUE(order_id)
这两个独特的约束条件确保一个订单只能属于一个客户,而且永远不会属于同一个客户两次。
你是否应该始终将这种关系正常化是一个不同的故事。在某些情况下,非规范化可能会导致更简单的实现。
答案 2 :(得分:5)
因此,可空的概念 外键似乎与之不一致 外键的目的,即 强制执行此约束。
外键的目的是明确概念,Orders表中的随机整数实际上是指Customers表中的一个项目。实际上强制执行作为约束是偶然的。
答案 3 :(得分:3)
在sql脚本
下设置外键可空或null使用ALTER TABLE Return_COMMENTS MODIFY order_ID Number NULL;
答案 4 :(得分:1)
有一些树结构,一个与自身相关的表。考虑一下:
table_node(node_id, parent_node_id, name)
对于root,parent_node_id应为null,对吗?
答案 5 :(得分:0)
将列设置为null的常见设计方案是,如果您具有一对多父子关系,但子项不必存在。
当父记录(如帐户)有可删除的子项(如帮助请求)时,这是一个很好的用法。
您可能有一个MostRecentRequest列,其中包含最新帮助请求的ID。从系统中删除请求时,MostRecentRequest列设置为NULL,表示不存在。
另一个例子是当你想要NULL表示还没有为父分配一行时。也许您有来自的帮助请求,技术人员字段中的NULL表示没有为该请求分配技术。当您删除该技术人员时,您希望所有未完成的工作通过将值重置为NULL返回池中。
答案 6 :(得分:0)
我们有很多这样的东西,因为我们的应用程序是从事件的一些基本信息开始并且随着时间的推移,因为事件更充分地计划,添加了更多信息。但是当添加信息时,我们希望确保它符合FK约束。 FK用于数据完整性,但在插入初始数据时并不总是知道所有数据,因此允许空值。
答案 7 :(得分:0)
还有另一种我能想到的情况:
在一个表中,您有一个唯一标识该记录的ID字段。同一记录可能(或可能不)有单亲。
包含以下列的表:
使用外键约束,您可以确保如果该字段不为null,则它引用有效的父级。此外,如果您尝试删除父记录而不修复子项,则无法删除父项。