必要的可空外键的任何示例?

egg*_*rop 18 database foreign-key-relationship

Customers
 customer_id

Orders
 order_id
 customer_id fk
Run Code Online (Sandbox Code Playgroud)

如果我有两个表并在Orders表中的customer_id上定义了一个外键,通过允许它为null,我说我可以订购一个没有客户关联的订单.因此,可以为空的外键的概念似乎与外键的目的不一致,即强制执行此约束.

是否有一个简单的例子表明可以使用可以为空的外键?或支持允许他们的论据?

n3r*_*3rd 48

想象一下拥有团队TODO的表格.如果尚未将TODO分配给团队成员,则其user_idNULL.如果不是,NULL它是users表的外键.

  • eggdrop询问是否有一个用例,其中一个空FK是"必要的",而不是"可能".这个答案具有误导性,因为它表明这样的情况存在于一个不支持结论的例子中:添加UserTasks(user_id,task_id)表,其中user_id作为其PK,task_id作为FK到TODO表将支持确切的相同的用例,仅使用空值.问题仍然存在,哪种方法更好,但我不相信存在无法避免空FK的用例. (14认同)
  • 许多人更喜欢的替代方案是拥有一个"未分配"用户并为其分配未分配的TODO.然后,您可以使列NOT NULL.大多数关于数据库设计的书都会详细讨论这个问题. (5认同)
  • RE:Neil Butterworth我已经使用过这样一个系统,我可以说NULL更明显(什么更好描述什么都没有)现在如果性能轮询显示NULL外键是一个问题然后避免它们,实际上这就是为什么系统会这样做,但否则你就是在做一个过早的优化.(恕我直言) (2认同)

mol*_*olf 16

没有,空的外键是永远需要的.

您始终可以规范化可选的1-many关系.举个例子,你可能有以下表格:

Customers: customer_id, ...
Orders: order_id, ...
OrdersCustomers: order_id, customer_id
  UNIQUE(order_id)
Run Code Online (Sandbox Code Playgroud)

这两个独特的约束条件确保一个订单只能属于一个客户,而且永远不会属于同一个客户两次.

是否应该始终规范这种关系是一个不同的故事.在某些情况下,非规范化可能会导致更简单的实现.

  • +1,但我不同意最后一段.非规范化只是表面上简化了事情.从长远来看,它总会咬你.这样做的唯一有效理由是容纳当前的SQL引擎,通过在正确的规范化存在下执行不良来惩罚您.(正确设计的关系引擎将允许您定义上面的规范化模式以及自动且完全透明的映射到高效的非规范化存储布局,从而为您提供两全其美的优势.) (2认同)

Jam*_*ran 5

因此,可以为空的外键的概念似乎与外键的目的不一致,即强制执行此约束.

外键的目的是明确概念,Orders表中的随机整数实际上是指Customers表中的项.实际上,强制执行作为约束是偶然的.