【问题标题】:Does Stack Exchange's database schema follow good practice? [closed]Stack Exchange 的数据库架构是否遵循良好实践? [关闭]
【发布时间】:2014-08-08 15:46:09
【问题描述】:

这有点像元问题,但因为它与数据库设计有关,我想我应该在这里发布。

我正在构建一个包含 Q+A 的网站,并且想知道我应该如何构建我的 SQL 数据库,所以很自然地,我查看了 best of the best。但是,Stack Exchange 数据库架构似乎不同意 what I've learned 关于创建可维护/可扩展表层次结构的问题。

如您所见,Stack Exchange 将其所有“帖子”存储在一个表中,但 cmets 除外,它有自己的表。帖子类型包括问题、答案和各种 wiki 内容。这会导致表中有很多 NULL 列。例如,问题有标题、标签和 answerCounts,而答案没有,因此所有答案条目对于所有这三列都为 NULL。如果随着时间的推移添加更多的帖子类型,这将逐渐变得难以维护。而 cmets 是唯一拥有自己表格的帖子类型这一事实似乎并不一致。

我读到的内容表明,通常首选使用对象子类层次结构,其中有一个通用的“帖子”表以及每种类型的帖子的一堆表,它们都有一个列映射回“帖子”表中的相应条目。这将空列的数量保持在最低限度并使其更具可扩展性,但会减慢查询速度,因为它们需要更多的连接。

那么为什么 Stack Exchange 使用这种巨表方法呢?这仅仅是对旧数据库进行多年修改的结果吗?更具体地说,我应该将此模型用于我自己的 Q+A 系统还是坚持使用对象子类层次结构(我的 Q+A/论坛系统将非常类似于 SO,有几种类型的帖子,包括问题、答案、投票、评论等.)?

【问题讨论】:

  • 它的可维护性如何?此外,您一直在阅读错误的内容。阅读马丁·福勒。他建议将单表继承作为首选策略。

标签: sql database database-design relational-database database-schema


【解决方案1】:

这是所谓的“Object-relational impedance mismatch”的经典案例。具体来说,您正在考虑将 OO 的继承映射到关系数据库结构中。有几种常见的方法-

  • 每个子类一个表,
  • 每个叶子类一个表,并且
  • 每个类层次结构的表(带有鉴别器)

这些策略中的每一个都是完全有效的。此外,结构可以根据需要混合。

看起来 Stack Exchange 使用了每个类层次结构表的方法,PostTypeId 用作鉴别器。这种方法与他们可以采取的任何其他方法一样有效。从维护的角度来看,它也是最简单的一种,因为它可以让您以更少的工作量构建手动查询。

表格结构中还有一点您没有提到:它没有被规范化。具体来说,有AnswerCountCommentCount 字段存储可以通过聚合表获得的信息(即运行SELECT COUNT(*) FROM ... WHERE ... AND other.ParentId = p.Id ...)这是规范化和执行速度之间的常见权衡:很可能,分析表明聚合需要大量时间,因此计数已移至“父”记录中。

【讨论】:

  • 我明白了,所以我想拥有大量空列是完全没问题的?另外,我不明白您所说的“看起来 Stack Exchange 使用了每个类层次结构方法的表”是什么意思,因为在我看来,它们对于所有类只有一个表。我确实注意到缺乏标准化,我发现它完全合乎逻辑,但我不明白它是如何相关的。
  • @JohnQian Posts 表存储单个类层次结构的所有对象的数据,包括问题和答案子类,以及 AbstractPost 的基类。注释表保存由单个类Comment 组成的单独类层次结构的数据。还有一个单独的用户层次结构。我提到缺乏规范化可能会偏离最佳实践。
猜你喜欢
  • 1970-01-01
  • 2021-11-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-08-12
  • 1970-01-01
相关资源
最近更新 更多