假设您有一个带有客户ID外键的订单表。现在,假设您要添加一个没有客户ID的订单,(是否应该是另一个问题),您将必须使外键为NULL ...是一种不好的做法,还是宁愿使用之间的链接表订单和客户?尽管关系为1到n,但链接表会将其设为n到n。另一方面,有了链接表,我不再有那些NULL了...
实际上,数据库中不会有很多NULL,因为带有外键NULL的记录只是暂时的,直到添加订单的客户为止。
(在我的情况下,它不是订单和客户)。
编辑:链接到未分配的客户呢?
假设您有一个带有客户ID外键的订单表。现在,假设您要添加一个没有客户ID的订单,(是否应该是另一个问题),您将必须使外键为NULL ...是一种不好的做法,还是宁愿使用之间的链接表订单和客户?尽管关系为1到n,但链接表会将其设为n到n。另一方面,有了链接表,我不再有那些NULL了...
实际上,数据库中不会有很多NULL,因为带有外键NULL的记录只是暂时的,直到添加订单的客户为止。
(在我的情况下,它不是订单和客户)。
编辑:链接到未分配的客户呢?
Answers:
拥有链接表可能是一个更好的选择。至少它不违反规范化BCNF(Boyce-Codd规范形式)。但是我更愿意务实。如果这些空值很少,并且它们只是临时的,我认为您应该跳过链接表,因为它只会增加方案的复杂性。
附带说明;使用链接表不一定使它成为n到n,如果您在链接表中使用指向订单表的外键作为该链接表中的主键,则该关系仍然为1..n。每个订单在该链接表中只能有一个条目。
根据我所读的内容,可空列可以是1NF到5NF,但不能是6NF。
只有当您比Chris Date更好地了解“首个范式真正意味着什么”时。如果x和y都可以为空,并且实际上在某些行中x和y都可以null
,则WHERE x=y
不会产生true
。毫无疑问,这证明null不是值(因为任何实际值始终等于其自身)。而且由于RM规定“表的每个单元格中都必须有一个值”,所以任何可能包含空值的事物都不是关系事物,因此甚至不会出现1NF问题。
我听说它认为Nullable列通常会破坏第一个标准化程度。
请参见上文,了解该论点的合理原因。
但实际上,这是非常实用的。
仅当您可以避免在世界其他地方通常会引起的头痛时才可以免疫。一个这样的头痛(相对于其他null
现象,这只是一个小问题),它WHERE x=y
在SQL中实际上意味着WHERE x is not null and y is not null and x=y
,但大多数程序员根本不了解这一事实,只是阅读了一下。有时没有任何伤害,其他时候则没有。
实际上,可为空的列违反了最基本的数据库设计规则之一:不要在一个列中组合不同的信息元素。空值之所以如此,是因为它们将布尔值“此字段确实存在/不存在”与实际值结合在一起。
我看不出有什么错,它只是一个可选的n-1关系,将在外键中用null表示。否则,如果您放置链接表,则必须管理它不会成为nn关系,从而造成更多麻烦。
如果您只是暂时添加没有客户ID的订单直到定义了客户,那么在单个交易中添加客户和订单会不会更简单,从而消除了对NULL外键输入的需求并避免了任何约束或触发器你设置被侵犯了吗?
通常,这种情况出现在Web应用程序中,在客户定义其身份之前先详细说明订单。在这种情况下,订单将保持服务器状态或cookie的状态,直到提供了完整订单的所有必要状态为止,此时订单将被持久保存到数据库中。
如上所述,对于地址之类的东西,可以使用NULL外键。但是NULL客户字段对于订单没有意义,应该加以限制。
您总是可以向客户表中添加一个人造行,例如Id = -1和CustomerName ='Unknown',然后在通常将OrderId中的CustomerId设置为-1的情况下。
这使您没有可为空的FK,但仍然可以适当地表示缺少数据(并将您从不知道如何处理NULL的下游用户中拯救出来)。