【问题标题】:One-to-one relationship or NULL field for optional column?可选列的一对一关系或 NULL 字段?
【发布时间】:2013-12-31 19:30:00
【问题描述】:

我正在进行数据库设计并希望存储用户地址。请考虑以下几点:很多时候,当您在网站上注册地址时,会出现“地址行 1”和“地址行 2”。

由于“地址行 2”是可选的,存储它的最佳做法是什么?

您是要使用单个表并允许“地址行 2”为 NULL,还是要创建一个具有一对一关系的单独表?

仅供参考,我的数据库使用 MySQL。

【问题讨论】:

  • 一个可以为空的字段。如果为每个可以为 null 的字段添加一个表,那么小型数据库将拥有数千个表。
  • 以上都不是 - 一个不可为空的字段,默认为单个空格。在可能的情况下,避免不得不合并可空字段的麻烦。获得直观的布尔结果。
  • @juergend 的回答是更被接受的方法。 null 定义的一件事是“没有价值”,这里就是这种情况。空值的存在是有原因的;这是其中之一。
  • 我会使用单表并将地址 2 设为空,一路易于维护。不需要为了查询结果而加入表
  • @EdGibbs:虽然这是一种常见的做法,但我认为 NULL 的更好语义是“可能有价值,但尚不清楚”,它减少了重复键入合并操作的需要。

标签: mysql database database-normalization denormalization


【解决方案1】:

以上都不是 - 默认为单个空格的不可为空的字段。在可能的情况下,避免不得不合并可空字段的麻烦。获得直观的布尔结果

在这种情况下,创建单独的表是错误的真正原因是地址标签只有两个地址行的空间。因此将两条地址行存储在主表中。

在其他情况下,可能值的最大数量确实是未知的,因此单独的表是正确的(至少在理论上,可能存在压倒一切的实用性考虑)。

更新: 请注意,在此示例中,所有空格 的值已经是一个特殊值,必须进行特殊处理 - 通过省略打印的地址标签(或其他显示介质)。添加一个额外的特殊值 NULL,具有相同的语义和对印刷标签的处理是不必要的浪费广告。

【讨论】:

  • 我不熟悉第二个地址行上下文中的全空格特殊值。这是标准做法吗?我想在数据库到邮件合并的直接关联中,如果不过滤 NULL,可能会出现问题。
  • @TomPace:您多久会在街道地址和城市/州行之间看到空白行?邮局自动分拣甚至会因此而感到困惑。如果需要一个空行来垂直对齐地址,它应该出现在顶部而不是地址的中间。附言我从不相信程序会隐式地正确处理我的NULL。如果文档中宣传的处理方式不是我想要的,我会合并为一个合适的值。
  • 听起来您对印刷格式非常熟悉,但我不熟悉。然而,我有丰富的展示经验,考虑任何一种情况都是微不足道的。没有给出打印的案例,即使如此,提问者的先入为主的想法也没有表明空白行是第三个选项。正如提问者所建议的那样,我确实同意你关于主表的观点。
  • @TomPace:这个例子确实是微不足道的。然而,在数据库设计中每次使用可空字段都会引入另一个实例,其中在构造布尔条件时必须考虑模态逻辑,从而丢失了我们在我们的研究中都认为理所当然的排除中间假设。思维。我厌倦了键入所有不需要强制使用的合并操作。
  • 我曾计划进一步了解您的观点,这也是您强烈反对 NULL 的原因。我确实尊重您对您的设计偏好被否决而感到沮丧,并且我可以看到您反对 NULL 的观点,但是为了提供简化的可访问答案(这通常是初级程序员所需要的),我采用了标准。如果提问者阅读了这个讨论并接受了你的回答,那我很好。
【解决方案2】:

我同意 Pieter Geerkens 关于使用主表的观点。

但是,如果您的设计需要有关该额外第二行的元信息,例如名称标签或第二行类型,例如“floornum”、“appartmentnum”的枚举, “buildingnum”,这是使用第二个表的情况。

.. 但除此之外,存储在主表中。如果你这样做了,我的答案是使用NULL 值。这是绝对没有存储任何东西时的标准默认值

【讨论】:

  • 我相信你误解了我的问题。用户到地址确实是一对多的,但是我关心地址的结构。例如,第 1 行通常是街道和门牌号,而第 2 行是可选的,但如果有的话,也可以用于公寓号码之类的内容。
  • @TomPace:现在,地址行的显示代码必须测试 both 行是否为空,以及是否为所有空格;或不断地将 null 合并到一个空格以执行简单的比较。为什么要让简单的任务变得更复杂?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-09-23
  • 1970-01-01
  • 2016-06-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多