数据库体系结构,列中的大多数空字段

时间:2018-08-22 08:56:14

标签: mysql database database-design

我在MySQL中有一个数据库表,根据一项新功能,我们可以通过两种方式实现- 1.在同一个表本身中创建一个新列(可为空),这种方法的缺点是-该列将具有95%到98%的NULL条目次数。 2.使用现有表的外键创建一个新表。

所以两种架构看起来都是这样-

1. table1 - <id, ..., new_column>

2. table1 - <id, ...>, table2 - <id, table1_id, ...>

第一种方法遵循非规范化方法,而第二种方法遵循规范化方法。但是由于这是一个现实问题,所以有时可以采用非规范化方法。

在我对数据库设计的某些假设中我可能是错的,您认为解决此类问题的更好方法是什么?

2 个答案:

答案 0 :(得分:1)

如果您可以提供特定的示例,这将非常有帮助-“我应该添加一个可能为空的列”很难回答。

非常通用术语进行归一化,直到可以证明必须做其他事情为止。设计数据库的易读性和防错性;添加额外的表所花的精力要比弄清楚为什么为什么当您更改一些意外忘记了非规范化的代码时,您的应用程序突然在12个月内报告不正确的数据。

那么,此可空列是否是实体的属性?并非所有people都具有middle name属性-具有可为空的列是完全合理的。还是因为方便而只是将其附加到实体上,但实际上不是属性吗?

例如,person可能有employer,而雇主可能有address;理想情况下,您将创建一个具有employer属性的address表;将employer_address附加到某人可能会觉得很捷径(除了地址,我不在乎其他任何东西,我永远不需要知道有多少人为该雇主工作)。

这似乎感觉上是您在节省一些时间-但它不太清晰(因此将来的开发人员会怀疑您为什么这样做),更容易发生错误(对于单个雇主而言,您可能会得到不正确或不一致的地址),并且更加困难改变未来(祝您好运,仅根据地址确定有多少人为给定的雇主工作)。

答案 1 :(得分:0)

在这些情况下,“垂直分区”可能是有利的

  • 第二个表中的列通常丢失,因此该表中的行较少。注意:您可以使用NULL来获得LEFT JOIN
  • 第二个表中的列很大,但很少使用。进行SELECT *会有性能劣势,并且某些列是TEXT / BLOB。垂直分区可以帮助您提高速度。 (在InnoDB中选择适当的ROW_FORMAT实际上消除了这一优势。)
  • 最常见的查询不需要第二个表的列。
  • 一定要添加具有停机时间的列。根据MySQL / MariaDB版本的不同,主表上的ALTER .. ADD COLUMN ..可能会长时间阻止其使用。

我怀疑这种方式只能拆分100个表格中的1个。这使读者感到困惑,等等。我上面列出的好处很少,并且这些好处可能不足以证明这样做是合理的。

第二个表将具有与主表相同的PRIMARY KEY,但没有AUTO_INCREMENT。这两个表将没有相同的辅助键。并请注意,您不能有一个包含两个表中的列的复合索引。

如果新列是一堆“属性”,例如在“商店”应用程序中,请考虑将它们放在JSON列中。这是开放式的,但是笨拙地不能与WHEREORDER BY一起使用。