数据库设计 - 空字段

时间:2010-05-01 20:48:48

标签: mysql database-design

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

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

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

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

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

我认为我很困惑,因为我正在讨论的内容并未被3NF所涵盖,而我通常将其用作如何构建数据的参考。

所以我的具体问题是: -

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

6 个答案:

答案 0 :(得分:10)

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

您的同事正在提出一些正在通往第6范式表的内容,其中所有表格都包含主键和最多一个其他列。只有在这样的模式中,我们才会有名为customer_info_fr的表。这没有正常化。许多国家/地区可能在地址中包含ENTRY_CODE。所以我们需要address_entry_codesaddress_floor_numbers。更不用说address_building_numberaddress_building_name,因为有些地方是按号码和其他名称来标识的。

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

答案 1 :(得分:5)

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

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

从您正在设计的声音中,我认为如果您想出一种在单个表中处理地址差异的通用方法,那么这将是最佳选择。您的代码和结构会在一些空数据字段的可忽略的(在我看来)成本上变得更加简单。

答案 2 :(得分:2)

无论你做什么,都不要沿着EAV路线走下去。这是一个表现不佳的数据库的处方,远比一些空字段差。

如果您必须为不同的情况设置单独的相关表格,那么很多情况将取决于实体的不同程度以及查询方式。如果您要跨类别查询,您会发现连接到一堆表以获取您可能需要或可能不需要的所有数据是一场噩梦(我不知道德国是否会在我的结果集中,所以我加入到德国细节表,哎呀不需要)。处理空值可能要简单得多,而不是试图找出你需要连接到的许多表中的哪一个(并且总是记住要连接到那些表)。

但是,如果您永远不会查看权限,并且字段有意义,请将它们放在单独的表中。

答案 3 :(得分:1)

这是可以为空的字段:“数据不可用/适用”。

SQL与大多数编程语言有着不同的null概念,因此SQL的null通常是一个被误解的概念。

答案 4 :(得分:0)

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

所有信息都可以准确无误地表示。由于nulls增加了复杂性,所以在没有它们的情况下开始你的数据模型是合理的设计实践,然后只在你发现某些特殊原因的地方添加一个null,或者某些数据库特性或限制迫使你无效。

答案 5 :(得分:0)

我不会想太多。可以使用NULL,但是开发人员需要谨慎使用它们。

对于与多个国家打交道的任何网站,我都希望在数据库中将“地址”设为长文本字段。

大多数网站都具有地址行1,地址行2,邮政编码,城市,州/地区,国家/地区……任何其他内容(例如EAV)都可能会过大。

我不介意让用户界面在每个国家的文本框附近显示不同的标签。

条目代码,楼层/级别,标题字段,安全编号等应适合地址行,其附近的标签或UI中的提示可以指示出来。