单个表与两个一对一相关表的性能

时间:2019-06-05 13:22:04

标签: sql database database-design relational-database

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

Countries
[PK]CountryId, CountryName, CapitalCityName, CapitalCityPostCode

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

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

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

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

3 个答案:

答案 0 :(得分:2)

在上面的示例中,对于Country和CapitalCities表,规范化不是很有用。一对一关系不会在读取和更新数据时造成任何重复或麻烦。如果数据需要国家和城市之类的表,而国家的首都为城市的fk,这将很有帮助。 从两个表中读取需要一个联接,这绝对比从单个表中读取要慢(不是很大)。有了几百个记录,看到的差异将是10到15毫秒。

答案 1 :(得分:1)

很明显,您可以看到第一种不是第三种正常形式。在性能方面,即使处理10亿个记录和数亿个记录时,正确标准化的表也将与第一个示例中的表相同。虽然平面文件总是会稍快一些,但是如果适当地关联的话,它的数量很少。第一个问题是随着时间的推移可伸缩性。如果需要增长,对于性能不稳定的基础,您会放弃一点性能提升

充其量是最大的差异。单张桌子总是会有一点优势;当您处理数亿条记录时,这一点会更加明显。但是,可以通过将表划分为相关的块来解决此问题,以便引擎可以对结果收集进行多线程处理,并根据连接和过滤条件消除大量不需要的记录。

与其他任何开发项目一样,没有一个灵丹妙药。规则总是有例外的。上下文对于每个问题都很重要。但是,广泛采用的方法表示,除非您知道永远不会增长,否则请正常化。 (从来都不是很长时间!但是,也许系统具有已知的保质期,并且永远都无法实现如此长的寿命。)

答案 2 :(得分:0)

通常,如果存在一对一的对应关系,则将数据拆分为两个表没有任何好处。如果没有冗余,则不是在“规范化”数据。如果您需要按城市搜索,只需指定将CapitalCityName列编入索引。您仍将获得搜索性能,并消除了必须为查询联接两个表的开销。

另一方面,如果每个城市的邮政编码很多(很常见),则需要一个单独的表格来规范化数据并提供每个城市(或特定城市的邮政编码)列表邮政编码)。但这带来了一个新问题:邮政编码可能不是唯一的:同一代码可能会在一个以上的国家中重复出现,甚至在某些情况下,“双城市”会共享一个共同的邮政编码。但这是另一个讨论的问题。