【问题标题】:DB design and performance: Is it OK to use redundant FK to increase performance?DB 设计与性能:使用冗余 FK 来提高性能是否可行?
【发布时间】:2012-08-13 19:24:39
【问题描述】:

假设我有以下数据库结构:

我的应用程序需要显示包含所有详细信息的文章列表(型号、产品系列、品牌、生产商)。为此,我需要进行更多的 JOIN 以获得所需的数据。

我是否可以通过为 Article 表创建冗余 FK 来提高应用程序的性能,如下所示?它真的提高了性能吗?

【问题讨论】:

  • 我看不出这会如何减少 JOIN 的数量。您仍然需要连接所有表以获取所有详细信息,只有连接 order 会有所不同(除非您对 ID 感兴趣,而不对详细信息表的其他列感兴趣)
  • 您为什么认为这会提高应用程序的性能?
  • 您可能是对的,当我需要获取所有数据时,冗余 FK 不会提高性能。

标签: database performance foreign-keys denormalization database-indexes


【解决方案1】:

确定设计是否能提高性能的最佳方法是尝试一下;第二种最好的方法是仔细考虑您可能需要运行的查询,然后尝试在您的脑海中对它们进行建模。如果不知道您要运行什么查询,或者您的数据库有多大,就很难知道您是否会看到性能改进。

一般来说,除非您有一个非常大的数据库(假设您在体面的硬件上运行它,并且您已经调整了索引),否则您不会看到对性能的可衡量影响。 “非常大”是指几个表中有数百万行。

如果你真的需要去规范化,我的建议是创建一个显式去规范化的表,而不是用冗余键“污染”你的常规设计。理解一个单独的“应该如何”和“妥协”的设计要容易得多,而不是将两者混合在一起。

为了实现这一点,我会创建一个单独的表 - 也许是“cached_articles”,其中包含列:

article_id
...(article data)
model_id
....(model data)
family_id
...(family data)
brand_id
....(brand data)
producer_id
....(producer data)

您可以通过批处理作业或触发器来维护此表。您应该只让您的应用程序代码写入规范化表,并且只在需要时从缓存表中读取。

您还应该建立一个强大的“一致性检查”机制来识别可能导致应用程序崩溃的数据问题;一旦您的数据库增长到需要这种设计的大小,这些一致性检查就会变得很重要,因为它们会遇到相同的性能问题......

【讨论】:

  • 感谢您的回答。它绝对是有趣的解决方案,但这会给应用程序带来更多复杂性(添加 cron 作业以进行同步),当我仅从“缓存”表中读取时,我不会获得最新的数据,这对我来说是必须的。
  • 如果更新很重要,可以使用触发器来更新表;我不喜欢触发器,因为它们往往会产生难以识别的错误,但它们非常适合这种事情......
【解决方案2】:

是的,如果您不想检索层次结构中“中间”对象的任何数据,您可以通过这种方式提高性能。这是一种常见的非规范化形式。请注意,您需要小心不要让不一致的地方溜进来。

我通常会设置一个夜间任务来验证非规范化数据,将错误发送给我并自动修复它们。这并不难做到,并且消除了一类令人讨厌的错误。

人们这样做的另一个原因是将所有表分区在同一个键上。

【讨论】:

  • 感谢帮助。我的观点是,并非每次我都需要所有信息。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-05-22
  • 2015-03-10
  • 1970-01-01
相关资源
最近更新 更多