【问题标题】:The dangers of hyper-normalization?超标准化的危险?
【发布时间】:2010-10-02 09:30:00
【问题描述】:

我和几位同事面临一个对性能有严重影响的架构决策:我们的产品包含一个 UI 驱动的模式构建器,它允许非程序员为 Web 应用构建自己的数据类型。目前,它在幕后构建了适当的规范化架构,并包含一些复杂的逻辑来更改架构并在管理员更改数据类型时自动迁移遗留数据。

规范化模式过去曾遇到过性能瓶颈,并且已安排进行重大重构。其中一组开发人员希望将数据类型的每个属性存储在单独的表中,以便对数据类型的更改永远不需要模式更改。 (单个属性可以转换为 1:n 关系,例如,只需更改应用程序逻辑。)

由于早期的基准测试表明这将导致巨大的性能损失,因此他们在应用程序代码中构建了一个缓存层,用于维护每种数据类型的非规范化版本。虽然它确实加快了查询速度,但我对应用程序层将承担的复杂性持怀疑态度,但我希望得到反馈——我是悲观的吗?其他人是否成功部署了此类解决方案?我应该坚持自己的立场,还是将复杂性从“架构修改工具”转移到“架构镜像工具”是一件好事?

【问题讨论】:

    标签: sql database-design architecture


    【解决方案1】:

    规范化的模式已经命中 过去的性能瓶颈, 并且进行了一次重大的重构 预定。其中一组 开发人员想要存储每个 a中数据类型的属性 单独的表,以便更改 数据类型永远不需要模式 改变。 (单个属性可以是 变成了 1:n 的关系,因为 例如,只需更改应用程序 逻辑。)

    这听起来对我来说是个坏主意。

    1. 它会破坏您的数据库性能。如果您将这些东西存储在一行中,它们将在物理上一起位于磁盘上,并且出于锁定等目的被视为一个东西。
    2. 您编写的查询将需要大量额外的连接,并且会非常痛苦。您最终将编写视图以将其恢复为最初应有的样子。
    3. 所描述的场景可能永远不会发生,因此您放慢了应用程序的速度并使其变得复杂而可能没有任何好处,
    4. 如果确实发生了这种情况,并且您将不得不重新编码和测试一堆应用程序代码,那么当时在进行数据库更改方面付出的额外努力是什么?您可以创建子表,通过更新将数据复制到其中,然后从父表中删除列
    5. 如果您成功了,将来可能会附加一个不同的应用程序到您的数据库。他们将无法分辨真正的模式是什么,因为该信息由您的应用程序保存。数据库中的模型数据。
    6. 如果 (a) 内存无法容纳太多,(b) 扩展到多个应用程序服务器,(c) 连接到数据库的不同应用程序,应用程序服务器上的缓存可能会变得棘手。您正在解决自己造成的性能问题。
    7. 如果多个列都存在于子表中,您将无法在多个列上创建索引。

    【讨论】:

    • 所有很好的观点和很好的解释。希望我能投票两次
    • 如果我在概念方面打他,而你在逻辑方面打他,也许我们会破坏这件事。 :D
    • 嗯,到目前为止,答案都证实了我自己对这个提议的改变的怀疑。感谢您的澄清论点...
    【解决方案2】:

    您所描述的与我所说的规范化不同。它更像是超抽象——试图找到一些抽象级别,从中可以派生出其他所有东西。就像 javascript 中的“对象”。如果您得出合乎逻辑的结论,则可以使用两张表。每个对象都有一个表,其中有一列用于 ObjectTypeCode 和 ObjectId;还有另一个带有关联的表,有两个 ObjectId 列,第三个用于唯一性,第四个用于 Value。

    我建议您需要重新审视您的域模型。你描述的那个对我来说听起来很可怕(但不幸的是,非常熟悉)。我有一个为我工作的人,他发明了一张名为“Objects”的桌子。有两个子表,ObjectAttributes 和 ObjectProperties。很难清楚地解释两者之间的区别。这张桌子(幸运的是他)并没有持续多久。

    【讨论】:

      【解决方案3】:

      严格来说,没有所谓的“超标准化”。如果一个完全规范化的模式被重构为另一个等效的完全规范化的模式,它们都被同等地规范化。通常所说的“超规范化”实际上是为了追求规范化以外的目标而进行的表分解。

      如果我没看错,我认为这不是你在原始帖子中概述的情况。似乎您的小组正在规范化模式和某种非规范化模式之间进行辩论。

      当这由聪明的设计师手动完成时,在某些类型的非规范化设计所获得的性能优势和随之而来的更新问题之间需要权衡取舍,不管是非规范化。我希望你做同样事情的产品会自动遭受与聪明的人类模式设计师相同的困难,然后是一些。

      我猜您网站的真正问题根本不是性能问题。相反,我认为这是让用户随意定义新数据类型的要求与从一组静态信息要求派生的精心设计的数据库中获得相同结果的愿望之间的冲突。

      在我看来,这两个目标是不可调和的。数据库中的最终数据管理层由您的用户社区完成。他们甚至可能不会在委员会中开会来决定哪些新定义将成为标准,哪些将被丢弃。除非我猜错了,否则架构可能充满了同义数据类型,不同的用户发明了相同的数据类型,但给了它不同的名称。它可能还包含一些同名的数据类型,不同的用户发明了不同的数据类型,但给了它们相同的名称。

      每次尝试都会导致混乱。这种混乱的第一个明显迹象是一个棘手的性能问题,但这只是冰山一角。迟早,您会发现数据库中的数据是非托管数据。而且您会发现,不可能像使用托管数据一样物有所值。

      如果我对此有误,我很想了解证明我错了的示例。这将代表最先进技术的根本性进步。

      【讨论】:

      • 这是一个很好的问题陈述,即。对高度抽象的要求和对性能的渴望之间的冲突。然而,友好的批评:这不是一个答案:-)
      【解决方案4】:

      我们亲切的 SO 团队已经解决了这个问题:Maybe Normalizing Isn't Normal

      结论-

      正如那句古老的格言所说,规范化直到它受伤,反规范化直到它起作用

      【讨论】:

        猜你喜欢
        • 2013-11-05
        • 1970-01-01
        • 2018-09-04
        • 2013-03-21
        • 2012-07-17
        • 2010-12-10
        • 2015-07-11
        • 2014-07-11
        • 2019-04-26
        相关资源
        最近更新 更多