mySQL - 我应该反规范吗?

时间:2009-11-13 13:26:50

标签: mysql database database-design denormalization

概述 (抱歉它含糊不清 - 我想如果我详细了解它会让事情复杂化)

我有三个表,表一包含一个id,表二包含自己的id和表一个的id,表三包含自己的id和表二的id。

我花了很多时间思考,我认为表3中包含相关表格id的效率会更高。

- 这意味着我不必加入三个表,我可以查询表三(对于将经常使用的查询)

- 通过仅锁定表3中包含来自表1的特定id的行,我将更容易实现预订系统。

对于想要了解有关数据库布局的更多信息的人,可以获得更多信息here

问题

去标准化有哪些不利因素?我见过一些完全反对它的人和其他相信正确情况的人,这是一个有用的工具。 id永远不会改变,所以除了必须两次插入相同的数据以及它将消耗的额外空间(因为它只是id的肯定可以忽略不计)之外,我真的没有看到任何缺点。

6 个答案:

答案 0 :(得分:5)

我的建议是遵循这个一般规则:默认情况下标准化,然后在识别出它将解决的性能问题时进行非规范化。

我发现规范化数据和处理它的代码,维护起来更简单,更合理。我不认为使用非规范化来提高性能有任何问题,但我不会推测性地应用任何性能优化,这会导致可维护性降低,直到您确定它们是必要的。

答案 1 :(得分:1)

你真正想要反规范化的唯一时间是它是否需要获得你想要的性能

已多次询问过这个问题。见here

答案 2 :(得分:1)

如果有充分理由,每条规则都可能被破坏。

在你的情况下,我想知道这三个表包含什么。表3是否真的描述了表二,还是直接描述了表一?

在这种情况下,表3中的self-id,table-two-id和table-one-id的缺点是,它可能导致不一致 - 如果你在表2中有table-one-id 1怎么办?表3中的表一号是错误的吗?

这取决于数据和数据的实体关系。对我来说,没有不一致并且在选择上有更多的时间更重要......

编辑:在阅读了关于你的表之后,我建议在表三(区域)中添加一个table-one-id,因为table-one-id毕竟没有改变,因此它相对保存了不一致性。

答案 3 :(得分:1)

由于一个(表1)到很多(表2),另一个一个(表2)到很多(表3)我会保持相同的结构,因为它们似乎是3层。

e.g。

  • 表1
    • 表2
      • 表3

此外,很多将取决于您在这些表中存储的其他字段。

答案 4 :(得分:0)

归一化与效率通常是一种权衡,而归一化通常是一件好事,它不是一颗银弹。如果你有明确的理由(就像你看到的那样),非规范化是完全可以接受的。

答案 5 :(得分:0)

包含少于完全规范化表的模式遭受所谓的“有害冗余”。有害冗余可能导致在多个地方存储相同的事实,或者没有任何地方存储需要存储的事实。这些问题称为“插入异常”,“更新异常”或“删除异常”。

总而言之,如果你在一个以上的地方存储一个事实,那么迟早你将在两个地方存储相互矛盾的事实,你的数据库将开始给出相互矛盾的答案,具体取决于查询找到的事实版本。

如果您被迫“发明一个虚拟记录”以便有一个存储所需事实的地方,那么迟早您将编写一个错误地将虚拟记录视为真实记录的查询。

如果你是一名超级程序员,并且你永远不会犯错误,那么你不必担心上述情况。我从来没有见过这样的程序员,虽然我遇到了很多以为他们从不犯错误的人。

我会避免将“非规范化”作为一种做法。这就像“远离芝加哥”。你还是不知道你要去哪里。但是,有些时候应该忽视规范化规则,正如其他人所指出的那样。如果您正在设计星型模式(或雪花模式),您将不得不忽略一些规范化规则以获得最佳星形(或雪花)。