Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/wix/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Database design 可空外键错误实践?_Database Design - Fatal编程技术网

Database design 可空外键错误实践?

Database design 可空外键错误实践?,database-design,Database Design,假设您有一个带有客户Id外键的表Orders。现在,假设您要添加一个没有客户Id的订单(这是否可行是另一个问题),您必须将外键设置为NULL。。。这是一种糟糕的做法,还是您更愿意使用订单和客户之间的链接表?虽然关系是1到n,但链接表将使其成为n到n。另一方面,有了链接表,我再也没有那些空值了 实际上,数据库中不会有很多NULL,因为外键为NULL的记录只是暂时的,直到添加订单的客户为止 (就我而言,这不是订单和客户) 编辑:关于要链接到的未分配客户呢?我看不出有什么问题,它只是一个可选的n-1关

假设您有一个带有客户Id外键的表Orders。现在,假设您要添加一个没有客户Id的订单(这是否可行是另一个问题),您必须将外键设置为NULL。。。这是一种糟糕的做法,还是您更愿意使用订单和客户之间的链接表?虽然关系是1到n,但链接表将使其成为n到n。另一方面,有了链接表,我再也没有那些空值了

实际上,数据库中不会有很多NULL,因为外键为NULL的记录只是暂时的,直到添加订单的客户为止

(就我而言,这不是订单和客户)


编辑:关于要链接到的未分配客户呢?

我看不出有什么问题,它只是一个可选的n-1关系,外键中用null表示。否则,如果放置链接表,则必须管理它不会成为n-n关系,因此会造成更多麻烦。

对于可选的多对一关系,可为空的FK完全可以。

不,可为空的FK没有问题。当FK指向的实体与主键引用表处于(零或一对(1或多)关系时,这是常见的


例如,如果表中同时具有物理地址和邮寄地址属性(列),并且FKs指向地址表。当实体只有一个邮政信箱(邮寄地址)时,您可以将物理地址设置为空,当邮寄地址与物理地址相同(或不相同)时,可以将邮寄地址设置为空。

使用空将是清理未完成订单的好方法:

SELECT * FROM `orders`
WHERE `started_time` < (UNIX_TIMESTAMP() + 900) AND `customer_id` IS NULL
从订单中选择*`
其中'started\u time'<(UNIX\u TIMESTAMP()+900)和'customer\u id'为空

上面显示的订单超过15分钟,没有相关的客户ID。

使用链接表可能是一个更好的选择。至少它不违反规范化(Boyce Codd范式)。然而,我倾向于务实。如果这些空值很少,而且它们只是临时值,我认为应该跳过链接表,因为它只会增加方案的复杂性


在旁注上;使用链接表不一定是n到n,如果在链接表中使用指向orders表的外键作为该链接表中的主键,则关系仍然是1..n。每个订单在该链接表中只能有一个条目。

我听说有人认为可空列通常会破坏第一级规范化。但在实践中,这是非常实际的

如果您只是临时添加订单,在定义客户之前没有客户id,那么在单个事务中添加客户和订单会不会更简单,从而消除对空外键条目的需要,并避免违反您设置的任何约束或触发器

通常情况下,这种情况在web应用程序中出现,在客户定义他/她是谁之前,订单是详细的。在这些情况下,订单将保持在服务器状态或cookie中,直到提供了完整订单所需的所有状态,此时订单将持久保存到数据库中


如上所述,对于地址之类的东西,空外键是可以的。但是空的customer字段对于订单没有意义,应该加以约束。

在关系模型中,可选关系绝对是可能的

可以使用null来表示没有关系。它们很方便,但它们会给你带来与null在其他地方给你带来的同样的麻烦。他们不会造成任何麻烦的一个地方是连接。外键中为null的行与引用表中的任何行都不匹配。所以它们从内部连接中退出。如果您进行外部联接,那么无论如何都要处理空值

如果您真的想避免空值(第六范式),可以分解表。两个分解表中的一个有两个外键列。一个是您拥有的可选外键,另一个是引用原始表主键的外键。现在,您必须使用约束来防止关系变成多对多,如果您希望防止这种情况发生的话


可以为空的列可以是1NF到5NF,但根据我所读的内容,不是6NF

除非你比Chris Date更清楚“第一范式的真正含义”。如果x和y都可以为null,并且确实在某些行中x和y都是
null
,那么
其中x=y
不会产生
true
。这毫无疑问地证明了null不是一个值(因为任何实际值总是等于自身)。由于RM规定“表的每个单元格中都必须有一个值”,任何可能包含null的东西都不是关系性的东西,因此1NF的问题甚至不会出现


我听说有人认为可空列通常会破坏一级规范化

参见上文,了解该论点背后的合理理由

但在实践中,这是非常实际的

除非你对它通常在世界其他地方引起的头痛免疫。其中一个头痛的问题(与其他
null
现象相比,这只是一个小问题)是,SQL中的
其中x=y
实际上意味着
,其中x不为null,y不为null,x=y
,但大多数程序员根本没有意识到这一事实,只是仔细阅读了一遍。有时没有任何伤害,有时没有

事实上,可空列违反了最基本的数据库设计规则之一:不要在一列中组合不同的信息元素。空值正是这样做的,因为它们将布尔值“this field is/not really present”和