数据库设计 - 空字段

use*_*927 13 mysql database-design

我目前正与我的开发团队讨论一个问题.他们认为空地是坏消息.例如,如果我们有一个客户详细信息表来存储来自不同国家/地区的客户的数据,并且每个国家/地区的地址配置略有不同 - 加上1-2个额外字段,例如法国客户详细信息也可能存储条目代码和楼层的详细信息/ level plus title fields(madamme等).南非将有一个安全号码.等等.

鉴于我们正在谈论微小差异,我的想法是将所有字段放入表中并使用每个表单上所需的内容.

我的同事认为我们应该有一个单独的表格,提供额外的数据.例如customer_info_fr.但是这种接缝首先完全打败了组合表的目的.

争论的焦点是空字段/列是坏的 - 但我很难在数据库设计原则方面找到支持或反对这个论点和首选解决方案的理由.

另一个选项是一个单独的迷你EAV表,它存储带有parent_id,key,val字段的额外数据.或者将额外数据序列化到主customer_data表中的extra_data列中.

我觉得我很困惑,因为我正在讨论的内容并未被3NF所涵盖,而这正是我通常用作如何构建数据的参考.

所以我的问题具体: -

如果每条记录的数据略有差异(例如1-2个不同的字段),最好的方法是什么?

APC*_*APC 10

绝对有一种思想流派认为NULL字段是坏的,在自己中.关系理论要求数据库由事实组成,而NULL则缺乏事实.因此,一个设计严谨的数据库将没有可空的列.

你的同事正在提出一些正在通往第6范式的东西,其中所有的表都包含一个主键和最多一个其他列.只有在这样的模式中,我们才会有表调用customer_info_fr.这没有正常化.许多国家/地区可能在地址中包含ENTRY_CODE.所以我们需要address_entry_codesaddress_floor_numbers.且不说address_building_numberaddress_building_name,如一些地方用数字标识和其他的名字.

作为一种逻辑设计,它是完全准确和真实的.从物理的角度来看,它是Teh Suck!最简单的查询 - select * from addresses成为多表连接,外部连接就是这样.可空栏目是一种协调丑陋设计与硬道理的方式,"你可以打破物理定律".可空列允许我们将不相交的数据集合并到单个表中,尽管以处理空值为代价(它们可能影响数据检索,索引使用,数学等).


zom*_*bat 5

我对你的同事关于为什么空地不好的理由感兴趣.据我所知,空字段或空字段本身并不坏.如果您计划在其上放置重要索引的列中有大量空数据值,则可能需要考虑其他选项.这适用于任何实际存在大量重复记录且需要索引的列,因为重复记录会降低的基数,从而使索引变得不那么有用.在你的情况下,我不认为这是一个问题.

对于这种数据,您可能无论如何都使用VARCHAR或某种TEXT列,它们是数据库中的可变长度字段.如果你的字段是满的数据或空的并不重要,你仍然会产生可变长度列的开销(在正常情况下这不值得担心).再说一次,RDBMS没有区别.

从您正在设计的声音中,我认为如果您想出一种在单个表中处理地址差异的通用方法,那么它就是您的选择.一些空数据字段的成本可以忽略不计(在我看来),你的代码和结构会简单得多.


nvo*_*gel 0

Null 总是会增加数据模型的复杂性,因为 SQL 中 null 的行为很少与您打算用它建模的数学、逻辑或现实相匹配。换句话说,某些查询返回不正确的结果,然后您需要使用额外的逻辑进行补偿。

所有信息都可以准确地表示,没有空值。由于空值会增加复杂性,因此在不使用空值的情况下开始数据模型是合理的设计实践,然后仅在您发现某些特殊原因或某些数据库功能或限制强制您使用空值时才添加空值。

  • 问题不是关于空值,他可以用空值切换空值,问题是关于稍微不同的实体的不同表或这些实体的同一个表的使用。分钟 1:( 这怎么可能是正确答案?我们从这个答案中学到了什么? (4认同)
  • 没有 null 就无法准确表示所有信息 (3认同)
  • 我不敢苟同。在 SQL 出现之前的数千年里,科学、数学和逻辑已经成功地在不使用 null 的情况下描述了世界。科学、数学和逻辑今天仍然如此。关系数据库无非是关于世界的一组命题。向该范例添加空值显然不会增加任何额外的表达能力 - 它只是意味着您有一组新的规则需要学习。除此之外,标准 SQL 中空值的使用非常不一致,以至于它几乎违背了您想要应用它的任何日常语义。 (3认同)