【问题标题】:What to do with null values when modeling and normalizing?建模和规范化时如何处理空值?
【发布时间】:2017-04-05 15:12:21
【问题描述】:

我是 SQL 新手(仍在学习),我必须为场地创建一个数据库。 用于活动房间的客户书。问题是客户并不总是提供他们的姓名、电子邮件和电话号码。大多数时候,要么是姓名和电子邮件,要么是姓名和电话。这很少是全部 3,但它会发生。 我需要将这些中的每一个存储在它们各自的属性(姓名、电子邮件、电话)中。但是他们给我信息的方式,我有很多空值。 我可以用这些空值做什么?我被告知最好不要有空值。之后我还需要规范化我的表格。 请有任何建议。

【问题讨论】:

  • AFAIK 表中的 NULL 值本身并没有错。更大的问题是 想用这些 NULL 值做什么?您希望数据库用默认值替换它们吗?或者,也许您想在将数据传递到 UI 或客户端时以特殊方式处理 NULL 值?

标签: postgresql null relational-database database-normalization


【解决方案1】:

SQL 根据其 3VL(3 值逻辑)版本特别对待 NULL。规范化和其他关系理论没有。但是,我们可以将 SQL 设计转换为关系设计并返回。 (假设这里没有重复的行。)

规范化发生在 relations 上,并且是根据不特别处理 NULL 的运算符来定义的。术语“normalization”有两个最常见的不同含义:将表放入“1NF”和“更高的 NF(标准形式)”。 NULL 不影响“标准化为 1NF”。 “标准化到更高的 NFs”用自然连接回它的较小的表替换表。出于规范化的目的,除了 SQL 类型的值之外,您可以将 NULL 视为可空列的域中允许的值。如果我们的 SQL 表没有 NULL,那么我们可以将它们解释为关系和 SQL 连接等作为连接等。但是如果您分解组件之间共享可空列的位置,然后意识到要在 SQL 中重建原始数据,您必须在 SQL 连接上同名列相等或都为NULL。而且您不希望在 SQL 数据库中出现这样的 CK(候选键)。例如,您不能将其声明为 SQL PK(主键),因为这意味着 UNIQUE NOT NULL。例如,涉及可空列的 UNIQUE 约束允许在该列中具有 NULL 的多行,即使这些行在每一列中具有相同的值。例如,SQL FK 中的 NULL 会导致它们得到满足(以每种 MATCH 模式的各种方式),而不是因为没有出现在引用的表中而失败。 (但 DBMS 与标准 SQL 有着特殊的不同。)

不幸的是,分解可能会导致一个表的所有个 CK 都包含 NULL,因此我们没有任何东西可以声明为 SQL PK 或 UNIQUE NOT NULL。唯一确定的解决方案是转换为无 NULL 设计。在规范化之后,我们可能希望在组件中重新引入一些可空性。

在实践中,我们设法设计表,以便始终有一组无 NULL 列,我们可以通过 SQL PK 或 UNIQUE NOT NULL 将其声明为 CK。然后我们可以通过从表中删除一个可为空的列并添加一个具有该列的表和一些无 NULL CK 的列来摆脱它:如果该列对于旧设计中的一行是非 NULL 的,那么一行它的 CK 子行和列值进入添加的表中;否则在旧设计中为 NULL,并且添加的表中没有相应的行。 (原始表是新表的自然左连接。)当然,我们还必须将查询从旧设计修改为新设计。

我们总是可以通过为每个旧的可空列添加一个布尔列并使旧列 NOT NULL 的设计来避免 NULL。新列针对一行说明旧列在旧设计中是否为 NULL,如果为真,旧列是否是我们为此目的在整个数据库中为该类型选择的某个值。当然,我们还必须将查询从旧设计修改为新设计。

是否要避免 NULL 是一个单独的问题。对于任何一种设计的应用程序,您的数据库可能在某种程度上“更好”或“更差”。避免 NULL 背后的想法是 it complicates the meanings of queries,因此与来自更多无 NULL 表的更多连接的复杂性相比,以一种不正当的方式使查询复杂化。 (通常通过在查询表达式中尽可能靠近它们出现的位置删除 NULL 来管理这种反常。)

PS 许多 SQL 术语(包括 PK 和 FK)与关系术语不同。 SQL PK 的意思更像是超级键; SQL FK 的意思更像是外键; but it doesn't even make sense to talk about a "superkey" in SQL:

由于 SQL 表与关系的相似之处,涉及关系的术语被草率地应用于表。但是虽然你可以借用术语并赋予它们SQL含义——值、表、FD(函数依赖)、超键、CK(候选键)、PK(主键)、FK(外键)、连接、谓词、NF (范式)、规范化、1NF 等——你不能仅仅用这些 SQL 含义来代替 RM 定义、定理或算法中的那些词,并得到一些合理或真实的东西。此外,RM 概念的 SQL 演示几乎从来没有真正告诉您如何将 RM 概念可靠地应用于 SQL 数据库。他们只是模仿 RM 演示文稿,不知道他们对术语的 SQL 含义的使用是否会使事情变得荒谬或无效。

【讨论】:

  • “非 NULL UNIQUE 索引允许多行在同一列中有 NULL” - 这可能是您选择的 SQL 产品中的行为,但我认为这与 SQL 标准相反。 ..“无论该列中的值是什么,总是认为在列中具有 NULL 的 FK(外键)是满意的”——我再次认为这是 SQL 标准的那些“依赖于实现”部分之一。我懒得去查了,因为底线是:SQL标准中对null和3VL的规定不一致,而且SQL产品与SQL标准不一致。
  • ...所以,虽然我很欣赏你在这里做了很好的尝试,但这最终可能是一个愚蠢的差事,就 SO 答案而言。 Hugh Darwen 的书“SQL:比较调查”试图使 RM 与 SQL 协调一致,并充斥着解释涉及空值的异常的“脚注”。
  • @oneday 当 Re“一个非 NULL UNIQUE 索引允许多行在同一列中具有 NULL”SQL 标准说 UNIQUE 和 DISTINCT 将具有 NULL 的行视为不同的行。 (虽然 SQL Server 没有。)“列中为 NULL 的 FK(外键)总是被认为是满足的”也是 SQL 标准,尽管在细节上它受 FK MATCH 模式的影响,其中通常只有 SIMPLE已实施。
  • 很高兴站起来更正!我绝对支持“避免 NULL 并通过删除查询表达式中的空值尽可能接近它们出现的位置来管理”人群:)
  • 释义@user2864740:在SQL Server 中,可以使用filtered index 来获得标准SQL UNIQUE 的等效项,其中允许NULL,其中多行可以在给定列中包含NULL,但每个子行在指定列上没有 NULL 的只会出现一次。
【解决方案2】:

首先,数据库中的空值没有任何问题。它们正是为此目的而制造的,其中属性未知。在我看来,避免在数据库中出现空值是一个毫无意义的建议。

因此,您将拥有三个(或四个)值 - 姓名(名字/姓氏)、电子邮件地址和电话号码 - 用于识别客户。您可以将它们放在表中并向其添加约束,以确保始终至少填充这些列中的一个,例如coalesce(name, email, phone) is not null。这样可以确保无法完全匿名进行预订。

从您的解释来看,您是否会始终从客户那里获得相同的信息并不清楚。那么,客户是否会以自己的名字预订一个房间,然后他们又以自己的电话预订了另一个房间呢?还是会在数据库中查找客户,找到他们的姓名并分配给他们的两个预订?在后一种情况下,您可以拥有一个客户表,其中包含到目前为止您获得的所有信息,并且预订将包含客户记录 ID 作为对该数据的引用。在前一种情况下,您可能不希望有一个客户表,因为您无法确定两个客户(Jane Miller 和 mrsx@gmail.com)是否真的是两个不同的客户或实际上只是一个客户。

到目前为止我看到的表格:

  • 房间 (room_id, ...)
  • 地点 (venue_id, ...)
  • 客户端(client_id、姓名、电子邮件、电话)
  • 预订(venue_id、room_id、client_id、...)

【讨论】:

  • “数据库中的空值没有任何问题” - 我知道你在那里做了什么:)
  • 数据库未知。通常我们知道为什么缺少一个值,或者我们根本不在乎。客户的电子邮件丢失。所以它没有给我们,我们不能使用它。在极少数情况下,我们有更多关于它的信息并想要使用它。如果您想知道电子​​邮件是否还没有给我们(我们应该再次询问客户),然后添加一个状态列。
  • 如前所述,通常没有必要。没有价格的产品只是没有最终确定的产品;我们还没有决定价格。没有删除日期的部门仍然处于活动状态,并且没有(逻辑上)被删除。没有默认增值税的产品组没有默认值,并且每个产品的增值税必须明确命名。我们创建数据库;我们知道没有价值意味着什么。
  • Erm,所以你同意“它们正是为此目的而制造的,属性未知”是错误的陈述吗?
  • 它的措辞可能不完美,但它仍然是正确的。 NULL 表示数据库未知的值。您存储了一个客户,但您没有他们的电话号码,因此您存储 null。
猜你喜欢
  • 1970-01-01
  • 2011-01-11
  • 1970-01-01
  • 2017-12-01
  • 2017-04-01
  • 1970-01-01
  • 2012-04-28
  • 1970-01-01
  • 2011-03-08
相关资源
最近更新 更多