【问题标题】:Single table vs two one-to-one related tables performance单表与两个一对一相关表的性能
【发布时间】:2019-10-21 00:23:35
【问题描述】:

假设我们要在关系数据库中存储以下数据:CountryNameCapitalCityNameCapitalCityPostCode。让我们假设一个城市只有一个邮政编码。我们可以用一种简单的方式在一个表中实现它:

Countries
[PK]CountryId, CountryName, CapitalCityName, CapitalCityPostCode

或者我们可以以更规范的方式将其排列成 1:1 关系的 2 个表:

 Coutries  
 [PK]CountryId, CountryName, [FK]CapitalCityId

 CapitalCities
 [PK]CapitalCityId, CapitalCityName, CapitalCityPostCode, [FK]CountryId

这将如何影响性能?例如 - 如果我们需要列出所有国家的首都名称,在第一种情况下会明显更快吗?我需要多少记录/列才能看到差异?

【问题讨论】:

  • 显然你可以看到第一个不是第三个范式。在性能方面,即使在处理 10 和数亿条记录时,正确规范化的表也将与第一个示例中的平面表相当。虽然平面文件总是会稍微快一点,但如果相关得当,数量会微不足道。第一个问题随着时间的推移变成可伸缩性。如果需要增长,您将放弃轻微的性能提升以换取不稳定的基础。
  • @xQbert 这确实回答了我的问题 - 您可以将其添加为答案而不是评论,以便其他人可以参考吗?
  • 性能差异取决于您在实践中访问表的方式。显然,所需键的额外存储增加了无谓的重量,并且必须执行连接会带来性能损失(以及额外的查询复杂性)。唯一可能的好处是,如果 Capital city 的列很少被读取,而 Country 的列被经常读取,并且两个表都非常大,在这种情况下,拥有一个精简的 countries 表可能会具有一些性能优势。然而,这可能是一个极端情况,只有在它已经出现的情况下才能解决。
  • 还可以考虑:stackoverflow.com/questions/1125004/… 作为以前的类似问题。

标签: sql database database-design relational-database


【解决方案1】:

很明显,您可以看到第 1 不是第 3 范式。在性能方面,即使在处理 10 和 100 条记录时,正确规范化的表也将与第一个示例中的平面表相当。虽然平面文件总是会稍微快一点,但如果相关得当,数量会微不足道。第一个问题随着时间的推移变成可扩展性。如果需要增长,您将放弃稍微提高性能以换取不稳定的基础

充其量只是边际差异。单桌总会有微弱优势;当您处理数亿条记录时,这会变得更加明显+。但是可以通过将表划分为相关块来解决这个问题,这样引擎就可以多线程收集结果并根据连接和过滤条件消除大量不需要的记录。

在任何其他开发中,没有单一的灵丹妙药。规则总是有例外的;每个问题的背景都很重要。然而,粗略的方法说,除非你知道永远不会增长,否则正常化。 (永远不会很长!但也许系统有一个已知的保质期,并且永远不会实现如此长期的存在。)

【讨论】:

    【解决方案2】:

    在上面的示例中,对于 Country 和 CapitalCities 的表,标准化不是很有帮助。一对一的关系在读取和更新数据时不会导致任何重复或复杂性。如果数据需要 Country 和 City 之类的表,且 Country 的首都为 City 的 fk,这将很有帮助。 从两个表中读取需要一个连接,这肯定比从单个表中读取要慢(不是很大的幅度)。对于数百条记录,所看到的差异将是 10 到 15 毫秒。

    【讨论】:

      【解决方案3】:

      一般来说,如果存在一一对应关系,那么将数据拆分为两个表没有任何好处。如果没有冗余,您就不会“规范化”数据。如果您需要按城市搜索,只需指定对 CapitalCityName 列进行索引。您仍将获得搜索性能,并消除了为查询连接两个表的开销。

      另一方面,如果每个城市有许多邮政编码(非常常见),则需要一个单独的表格来规范数据并提供每个城市(或特定城市的邮政编码)的列表邮政编码)。但这带来了一个新问题:邮政编码可能不是唯一的:相同的编码可能在多个国家重复使用,甚至存在“双城”共用一个邮政编码的情况。但这是另一个讨论的问题。

      【讨论】:

      • 别说有些城市有multiple post codes;所以这个结构不支持这个概念。该链接是针对芝加哥的;但 DC 有数百个邮政编码;每栋建筑都有一些!
      • 好吧,这不是一个完美的例子。我补充说,我们假设一个城市有一个邮政编码。但除了标准化 - 我只对这两者之间的性能差异感兴趣。
      • 充其量只是边际差异。单桌总会有微弱优势;当您处理数亿条记录时,这会变得更加明显。但是可以通过将表划分为相关块来解决此问题,以便引擎可以多线程收集结果并根据连接和过滤条件消除大量不需要的记录。与任何其他发展一样,没有一颗银弹。规则总是有例外的;每个问题的背景都很重要。粗略的方法说,除非你知道没有增长,否则正常化。
      猜你喜欢
      • 1970-01-01
      • 2021-04-09
      • 1970-01-01
      • 1970-01-01
      • 2014-06-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多