在 MySQL 中拆分表。好习惯?

Pin*_*uit 15 mysql database-design best-practices

我已经开始处理一个现有项目,之前的开发人员已将一个表拆分为 10 个单独的表,这些表具有相同的模式但数据不同。

表格如下所示:

[tableName_0]
[tableName_1]
[tableName_2]
[tableName_3]
[tableName_4]
[tableName_5]
[tableName_6]
[tableName_7]
[tableName_8]
[tableName_9]
Run Code Online (Sandbox Code Playgroud)

主键是一个整数id字段。该应用程序使用哈希算法 ( idmod 10) 来了解在进行查找时要访问的表。例如id= 10 将导致[tableName_0].

结合起来,这些表大约有 100,000 行,增长率相对较低。

所以,我的问题是这是否是一个可行的解决方案,或者它是否在任何情况下都是一个很好的做法。我的理论是推动将它们结合起来,因为它会使事情变得更容易UNION,等等。主要的缺点是更改所有应用程序代码以及从长远来看是否值得。

Nic*_*mas 18

我认为每个人都把这个问题复杂化了。这里的关键是:

结合起来,这些表大约有 100,000 行,增长率相对较低。

这对于任何 RDBMS 来说都是小菜一碟使用一张表,正确索引它,并将其视为已解决的问题。

您不需要考虑分区,无论是“自制的”还是其他方式,直到您开始处理大量数据——想想数十亿行甚至更多。


atx*_*dba 3

您可以使用合并表,但它们在 4.x 版本中已经过时了。鉴于您的应用程序是手动分区的,因为它要么 a) 您运行的是非常旧的版本,要么 b) 原始开发人员不知道表分区。

简而言之,如果您运行的是 5.1+,您可以让 mysql 为您完成此分区。请参阅 http://dev.mysql.com/doc/refman/5.1/en/partitioning.html 如果您使用5.5,您应该检查这些特定文档,因为您会发现一些差异。

分区有很多优点。然而,这实际上取决于手头的数据集、访问模式以及如何对其进行索引。另外,请记住我的以下评论是在 mysql 5+ 分区的上下文中,而不是旧的 mysql 合并表;尽管有时会根据分区来讨论它们。

一些例子:

  • 基于频繁访问的查找键的直接分桶(或散列)。如果您几乎总是通过主键或其他唯一键进行查找,那么 mysql 可以根据您拥有的分区数量来削减搜索空间。但请注意,如果您按一个键进行分区,然后频繁地按另一个键进行搜索,则这可能是有害的。如果您按某个键搜索数据未分区,那么它必须在查找上进行更多搜索(每个分区一个,坦率地说,它不知道数据在哪里)
  • 考虑这样的情况:您有一组按日期增长的临时记录,并且定期删除上个月的记录。如果您按日期分区,那么您可以简单地删除一个分区,这与删除表一样快,无论有多大。如果您要按日期修剪这样的表,则必须发出一个或多个 DELETE 查询,其中删除每一行。这样做的缺点是,一旦达到了在这种情况下所考虑的最大日期,mysql 不会自动创建新分区;您需要构建额外的维护脚本来根据需要添加分区。
  • 如果您使用 myisam,检查和恢复速度会更快。考虑一个 100G myisam 表。如果你想恢复崩溃的表,你至少需要大约 100G 的空闲磁盘空间。如果将其划分为 10 个相同大小的不同块,那么您只需要 10G 空间(以及更少的 key_sort_buffer 内存以实现快速恢复);但需要对每个分区进行迭代。

总而言之,分区表的一般方法可以带来很多好处。然而,在不考虑访问模式和分区方式的情况下盲目应用它并不是灵丹妙药。

我可以想象这样的情况:所需的分区是非常特定于应用程序的,并且更适合将该逻辑放在应用程序层中。然而,考虑到您的直模数 10 描述,这似乎不是这样的情况。

编辑

在写我的描述时,我忘记了你说过你的表有 100K 行。如果没有表的完整模式和平均行长度,很难确定,但总的来说,即使对于适度的硬件来说,这听起来也是中等大小。同时,如果它不会像现在或在可预见的将来那样造成问题,那么就不要花费时间并通过改变它来引入风险。