为什么我们要将MySQL表分成许多较小的表?

11
似乎将一个表的数据分成多个数据库和多个表以提高性能是一种常见做法,我可以理解"多个数据库"这部分,因为更多的数据库提供了更多的CPU、内存和IO容量。但是"多个表"呢?为什么不使用MySQL分区http://dev.mysql.com/doc/refman/5.1/en/partitioning.html呢?
更新:我的意思并不是规范化。我是指将一个包含N条记录的表分成例如10个表,每个小表都有N/10条记录。
更新2:感谢@Johan对于"分片"和"分区"的澄清,特别是指出数据的"热点"属性。
@Johan没有回答的小问题是:举个简单的例子,假设我们有一个用户表,它有一个userid列(bigint)。我认为使用mysql-partition根据userid自动将表分成分区更容易,手动将表分成小表(基于userid)似乎没有好处,我是对的吗?

你在哪里看到这样的做法?我认为你所说的(根据行数细分表格)根本不是常见的做法。 - Scott C Wilson
不是离题,把它变成 CW 会更好,但分区的原因肯定与编程有关。许多人问“如何分区”(在话题范围内),然后答案总是“不要这样做,因为你不需要这样做”,表明人们忘记了问自己或他人“为什么要分区?”因此,在这个主题上进行讨论是很好的,这样 SO 可以看到分区的利弊。 - Johan
是的,完全正确:手动分区表是疯狂的,因为如果您想查询两个数据集,还必须手动使用unionjoin将它们重新组合。如果您使用分区函数,MySQL会为您完成所有工作。这意味着分区对您的应用程序透明,您的代码不会出错。双赢。 - Johan
2个回答

31

我认为你在这里混淆了一些术语。

所有的数据都存储在一个数据库中(也称为模式schema)。 在数据库中,你可以拥有多个表格(tables)。

例如:

table employee
   id integer
   name varchar
   address varchar
   country varchar

table office
   id integer
   employee_id integer
   address varchar

表格中有字段(id,name,address),也称为列。

表格有一行或多行。
以员工表为例:

id  name        address           country
----------------------------------------------------
1   John        1 Regent Street   UK
2   James       24 Jump Street    China
3   Darth Vader 1 Death Star      Bestine, Tatooine

以上是基础知识。

分区的原因
假设我们有大量人员(行)在我们的数据库中。
记住,这是一个银河系数据库,所以我们有1000亿条记录。
如果我们想要快速搜索,最好能够并行进行。
因此,我们对表进行分区(按国家分),然后我们可以让x个服务器每个服务器查找一个国家的信息。
跨服务器进行分区称为分片

或者我们可以将历史数据按年份分区,这样我们不必查看所有数据才能获得最近的新闻。我们只需要查看今年的分区即可。这被称为分区

分片分区之间的主要区别是什么?

分片
分片中,您预期所有数据都是相关的,并且同样可能被查询。(例如,Google可以预计他们的所有数据都会被查询;对于他们来说,存档部分数据是无用的)。
在这种情况下,您希望许多机器并行查看数据,每台机器都处理一部分工作。
因此,您为每台机器分配一个不同的数据分区(分片),并将相同的查询发送给所有机器。当结果出来时,您将它们全部UNION在一起并输出结果。

基本分区
在基本的分区中,您的数据部分热门,部分不受欢迎。典型情况是历史数据,新数据是热门的,旧数据几乎不被触及。
对于这种用例,在单独的服务器上放置旧数据是没有意义的。那些机器只会等待并且什么都不会做,因为除了一些年度审计人员谁需要看它之外,没有人关心旧数据。
因此,您按年份对数据进行分区,服务器将自动归档旧分区,使查询仅查看一(或两)年的数据,并且速度更快。

我需要分区吗?
只有当您拥有大量的数据时才需要分区,因为它会使您的设置变得复杂。
除非您拥有超过一百万条记录,否则无需考虑分区。*)
如果您拥有超过1亿条记录,则应该考虑分区。*)

更多信息请参见:http://dev.mysql.com/doc/refman/5.1/en/partitioning.html
和:http://blog.mayflower.de/archives/353-Is-MySQL-partitioning-useful-for-very-big-real-life-problems.html
另请参阅维基百科:http://en.wikipedia.org/wiki/Partition_%28database%29


*)这些只是我的个人启发法,可能因情况而异。


2
谢谢你,你帮助我更好地理解了分片和分区,特别是让我考虑数据是否热点。我已经阅读了这篇文章:http://blog.mayflower.de/archives/353-Is-MySQL-partitioning-useful-for-very-big-real-life-problems.html,它提到了mysql-partition的一些限制。在我看来,举个简单的例子,假设我们有一个用户表,使用mysql-partition根据user_id将表划分为分区比手动将表划分为小表要容易得多。因为mysql会处理所有事情。 - James.Xu
2
我甚至不关心数据库,但我觉得这很有趣。 - Mike Robinson

0

数据被分割成较小的表以进行“规范化”。这是一个非常有趣的概念。您可以在此处阅读更多相关信息。

http://en.wikipedia.org/wiki/User:Jaseemabid/Books/Database_normalisation

一个快速的例子。

假设有一个小型电话簿应用程序,允许人们拥有多个号码。

一种设计方式是这样的:

  • 姓名 | 号码
  • A | 123
  • A | 95467
  • B | 179

这种方式的问题在于,当我们需要更新A的姓名时,如果我们没有全部更新,就会造成混乱。因此,我们可以将其拆分为两个表,如下所示。

  • 唯一ID | 姓名
  • 1 | A
  • 2 | B

  • 唯一ID | 号码

  • 1 | 123
  • 1 | 95467
  • 2 | 179

这将解决这个问题。使用“外键”可以以令人惊叹的方式处理约束,请阅读相关内容以更好地理解整个概念。

希望你明白了 :)


谢谢你,但是你误解了我的意思。我不是指规范化,而是将一个包含N条记录的表分成例如10个小表,每个小表都有N/10条记录。 - James.Xu
1
分区并不等同于规范化,请阅读:http://en.wikipedia.org/wiki/Partition_%28database%29 和:http://en.wikipedia.org/wiki/Database_normalization - Johan

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