SQL数据库:规范化 vs. 性能?

6

为了一个项目,我被要求查看现有的SQL数据库并看看它是否可以改进。 它基本上是一个客户数据库,每个客户有各种不同类型的数据。 这就是(基本上)它的组织方式:

每个客户在客户表中都有一行,带有客户ID。 然后对于每种类型的数据,每个客户都有自己的表。 所以,例如,并没有一个名为“jobs”的中央表,每行都有一个客户ID,但对于每个客户都会有一个称为“jobs1234”的作业表(1234是客户ID)。

现在,我的第一反应是困惑,不知道为什么要这样组织。 我一直只是学习过规范化,而没有真正深入思考。 但当我与人讨论时,有些人指出可能是出于性能原因。 他们说,如果“工作”的行数太多,将它们分成每个客户比放在一个表中更好。

有关索引和客户ID作为标识符的某些内容。 我不明白为什么这种方法会提高性能,到目前为止我还没有得到非常清晰的答案。 有人能向我解释为什么情况是这样的,以及在某些情况下这种方法是否更好吗?


1
你所描述的与规范化无关。 - Mike Sherrill 'Cat Recall'
@MikeSherrill'Catcall',也许我误解了,但是:“数据库规范化是将关系型数据库的字段和表组织起来以最小化冗余和依赖性的过程”。这实际上与这种情况有很大关系,不是吗?如果您解释一下您的评论意思,而不仅仅说它是“错误”的话,那会更有帮助。 - vanamerongen
规范化关注列之间的某些依赖关系。您正在描述行之间的某些依赖关系。(“jobs1234”中的所有行都属于客户1234。)搜索该术语的名称为“分区”。所有当前的主要客户端/服务器DBMS都原生支持分区。我只会在万不得已时采用自己动手的方法。我甚至会考虑更改平台以避免自己动手。 - Mike Sherrill 'Cat Recall'
@MikeSherrill'Catcall' 啊,感谢你的回复。我还不知道这个术语呢。我所指的“规范化”部分是指彻底重建这个虚假的模式,而不是现在的组织方式,如果它给人的印象是这样的话。(那可能还是一个错误的词,但仍然如此) - vanamerongen
“重构”对此非常有效。规范化被广泛误解。可能有90%的问题是以规范化术语表达的,但与规范化无关。 (答案中也有90%如此。)如果您无法“识别”规范化问题,则更不可能正确解决规范化问题。 对于分区和索引问题也是如此。(这是一种观察,而不是批评。) - Mike Sherrill 'Cat Recall'
1个回答

19

我发现这个声明相当令人震惊:

  

他们说,如果“工作”行数过多,则将它们按客户拆分比将它们全部放在一个表中更好。

数据库的设计是具有大量行的表--数百万行应该没有问题。 您没有指定数据量,但是以 jobs 这样的名称,如果总量超过几百万行,我会感到惊讶。 对于此数据量,具有适当索引的单个表应该可以胜任。

在某些情况下,按客户拆分数据确实有意义。 最强烈的情况是它是一个显式的要求,通常出于安全原因。 换句话说,客户被承诺“他们的数据永远不会与任何其他人的数据混合”。 在大多数数据库(包括MySQL)中,在表级别处理安全性比在行级别处理更容易。

另一个可能的原因是当表具有不同的格式,反映每个客户的不同数据时。 在这种情况下,您实际上将处理单独的应用程序,并且每个客户都应该拥有自己的数据库。

将客户数据拆分为每个客户的多个表是否存在任何缺点? 是的。 以下是一些:

  1. 您无法编写通用的查询/视图来访问数据。 基本上,代码中的所有查询都需要是动态的,以便您可以放入正确的表名。
  2. 维护数据变得繁琐。 您不仅要更新单个表,还要更新多个表。
  3. 回答诸如“每个客户有多少工作?” 或“工作数量随时间增长了多少?” 这样的问题变得非常困难,以至于人们可能根本不会费心去问它们。
  • 性能是一个各有千秋的问题。虽然你可以节省在每个表中存储客户ID的开销,但你会承担另一种代价。拥有大量小表意味着有很多部分填充的表页。根据每个客户的工作数量和总客户数,您实际上可能会增加所需空间的数量。在每个客户只有一个作业的最坏情况下,如果一个页面包含--比方说--100个作业,则会将所需空间乘以约100倍。
  • 最后一点也适用于内存中的页面缓存。因此,在许多表之间分割时,可以适合放入内存的一个表中的数据可能无法放入内存中。
  • 分区是实现类似功能的一种方法。但是,当查询负载聚焦于一个客户端时,这将起到最佳效果。如果所有客户都同时访问数据,则分区将不会获得更多胜利,索引就足够了。

    除非有一个非常好的理由将数据分成单独的表(要求、每个客户繁琐的安全性或为每个客户定制的格式),否则你不应采用这种方法。即使存在进行此操作的原因,通常还有其他解决相同问题的解决方案(例如分区)。


    换句话说,客户被承诺“他们的数据永远不会与其他人的数据混合在一起。”我听说有些监管环境要求这样做,但我自己没有参与过这样的系统开发。 - Mike Sherrill 'Cat Recall'
    @MikeSherrill'Catcall' . . . 监管要求可能更加繁琐,需要在不同的机器上建立单独的数据库(有时甚至不在同一子网上)。数据分离是出现的原因(根据我的经验),当竞争公司共同合作开发某个系统以帮助该行业时。 - Gordon Linoff

    网页内容由stack overflow 提供, 点击上面的
    可以查看英文原文,
    原文链接