5

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

每个客户在客户表中都有一个带有客户 ID 的行。然后对于每种类型的数据,每个客户都有自己的表格。因此,例如,不会有一个用于“工作”的中央表,每一行都有一个客户 ID,但对于每个客户,都会有一个名为“jobs1234”的工作表(1234 是一个客户 ID。

现在,我的第一反应是不明白为什么要这样组织它。我一直只是了解到,在没有真正考虑超越这一点的情况下正常化总是更好。但是当我与人们讨论它时,一些人指出这可能是出于性能原因。他们说,如果“工作”的行太多,最好将它们按客户分开,而不是将它们全部放在一张表中。

关于索引和客户 ID 作为标识符的一些事情。我很困惑为什么这种方法会提高性能并且到目前为止还没有真正得到一个非常明确的答案。谁能向我解释为什么会这样,如果在某些情况下这种方法更好?

4

1 回答 1

18

我觉得这句话相当令人震惊:

他们说,如果“工作”的行太多,最好将它们按客户分开,而不是将它们全部放在一张表中。

数据库被设计成有很多很多行的表——数百万行应该没问题。您没有指定数据量是多少,但是如果使用类似 的名称jobs,如果总数据量超过几百万行,我会感到惊讶。对于这种数据量,具有合适索引的单个表应该没问题。

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

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

将客户数据拆分为每个客户的多个表有什么缺点吗?是的。这里有一些:

  1. 您不能编写通用查询/视图来访问数据。基本上,代码中的所有查询都需要通过动态查询,因此您可以输入正确的表名。
  2. 维护数据变得很麻烦。除了更新单个表之外,您还必须更新多个表。
  3. 回答诸如“每个客户有多少工作?”之类的问题。或“随着时间的推移,工作数量的增长是多少?” 变得如此难以回答,以至于人们可能甚至都懒得问他们。
  4. 性能好坏参半。尽管您可能会节省在每个表中存储客户 ID 的开销,但您会产生另一项成本。拥有许多较小的表意味着许多表的页面已部分填充。根据每个客户的工作数量和总体客户的数量,您实际上可能会成倍增加使用的空间量。在一个页面包含 100 个工作的每个客户一个工作的最坏情况下,您需要将所需空间乘以大约 100。
  5. 最后一点也适用于内存中的页面缓存。因此,一个表中可以放入内存的数据在拆分到多个表时可能不适合内存。

分区是实现类似功能的一种方式。但是,当查询负载一次集中在一个客户上时,这将最有效。如果所有客户都在同时访问数据,那么分区就不会那么成功了,索引应该就足够了。

除非有充分的理由将数据拆分到单独的表中(要求、每个客户端的繁琐安全性或每个客户端的自定义格式),否则您根本不会采用这种方法。即使有这样做的理由,也经常有其他解决方案(例如分区)可以解决相同的问题。

于 2013-07-27T18:05:20.580 回答