在 MySQL 中对数据库表进行分区

Posted

技术标签:

【中文标题】在 MySQL 中对数据库表进行分区【英文标题】:Partitioning a database table in MySQL 【发布时间】:2009-12-20 17:12:48 【问题描述】:

我正在编写一个数据仓库,使用mysql 作为后端。我需要根据两个整数 ID 和一个名称字符串对表进行分区。

一个更具体的例子是假设我正在存储关于一所学校的数据。我想根据 COMPOSITE 'Key' 对 school_data 表进行分区:

school id (integer)
course_id (integer)
student_surname (string)

对于学生姓氏,只是姓氏的第一个字符决定了数据应该进入哪个“分区表”。

如何使用 MySQL (5.1) 和 InnoDb 表来实现这个要求?

另外,我正在 Windows 机器上进行开发,但我将部署到 *nix 机器上进行生产。我还有两个问题:

    我假设在从 Windows 迁移到 Linux 时必须转储和恢复数据。如果数据库包含分区表,我不知道这是否可以(指向它在文档中声明的位置的指针会让我放心 - 我无法找到任何关于分区表的转储/恢复的具体提及。 我可能还需要更改数据库(如果 Oracle 对 MySQL 用户采取了出人意料的举措),在这种情况下,我需要以某种方式将数据导出到另一个数据库中。在这种情况下(希望不太可能发生的情况)——考虑到分区表,从 MySQL 中转储数据(可能是文本或其他内容)的最佳方法是什么?

【问题讨论】:

即使 Oracle 决定对 mySQL 进行修改,他们也确实无法让开源用户无法使用它。请注意,他们多年来一直在资助 InnoDB 开发。 【参考方案1】:

RANGE 分区

按范围分区的表的分区方式是,每个分区都包含分区表达式值位于给定范围内的行。

CREATE TABLE employees (
  school id (integer)
  course_id (integer)
  student_surname (string)
)
  PARTITION BY RANGE (student_surname) (
  PARTITION p0 VALUES LESS THAN ('ezzzzzzzzzzzzzzzzzzzzzzz'),
  PARTITION p1 VALUES LESS THAN ('ozzzzzzzzzzzzzzzzzzzzzzz'),
  PARTITION p2 VALUES LESS THAN ('tzzzzzzzzzzzzzzzzzzzzzzz'),
  PARTITION p3 VALUES LESS THAN (MAXVALUE)
);

Range partitioning

数据迁移到另一个数据库

MySQLDUMP 会将表和数据输出到文件中。但是,Oracle supports connecting to other databases via ODBC,就像 SQL Server 具有它的链接服务器功能一样。

附录

您似乎只按我提到的 3 个字段之一(即名称)进行分区。我在 MySQL 文档中看到了按单个字段进行分区,但没有像我想要的那样按 3 个字段(int、int、string)进行分区。

可以按三列进行分区,但我的示例是根据您在 OP 中的要求:

对于学生的姓氏,它只是姓氏的第一个字符,它决定了数据应该进入哪个“分区表”。

【讨论】:

看起来您只按我提到的 3 个字段之一进行分区(即名称)。我在 MySQL 文档中看到了按单个字段进行分区,但没有像我想要的那样按 3 个字段(int、int、string)进行分区。我正在考虑从 2 个 id 和姓氏的第一个字符动态构建一个字符串,但我不确定这是否有效(或者甚至可以工作)。 "我想根据 COMPOSITE 'Key' 对 school_data 表进行分区:" 这个解决方案对我不起作用。我收到一个错误:ERROR 1697 (HY000): VALUES value for partition 'p00' must have type INT 注意:我使用的是 MySQL 5.5,而不是 5.1,但似乎 5.5 也应该支持 varchar 列的范围分区。 【参考方案2】:

如何使用带有 InnoDb 表的 mySQL (5.1) 实现此要求?

查看 MySQL 文档的 Chapter 18. Partitioning,尤其是 Partition Types(我会查看 HASH partitioning)。但请记住,MySQL 5.1 中的分区实现仍在开发中,还有一些limitations and restrictions。

我假设从 Windows 迁移到 Linux 时必须转储和恢复数据。如果数据库包含分区表,我不知道这是否可以(指向它在文档中声明的位置的指针会让我放心 - 我无法找到任何关于分区表的转储/恢复的具体提及。

我在18.3 Partition Management 中没有找到任何内容,但是根据this post 的说法,备份和恢复分区表并没有什么特别之处。备份:

mysqldump --opt db_name table_name > file.dump

然后恢复:

mysql db_name < file.dump 

不过我会做一些测试。

我可能还需要更改数据库(如果 Oracle 对 mySQL 用户采取了令人惊讶的举措),在这种情况下,我需要以某种方式将数据导出到另一个数据库中。在这种情况下(希望不太可能发生的情况)——考虑到分区表,从 mySQL 中转储数据(可能是文本或其他内容)的最佳方法是什么?

Oracle SQL Developer 通过包含重新开发的功能并大大扩展原始 Oracle 迁移工作台提供的功能和可用性来将 Microsoft Access、Microsoft SQL Server、MySQL 和 Sybase 数据库迁移到 Oracle,从而整合迁移支持。

【讨论】:

以上是关于在 MySQL 中对数据库表进行分区的主要内容,如果未能解决你的问题,请参考以下文章

在 Hive 中对表进行分区和分桶有啥区别?

sql 在Postgres中对表进行分区

如何在 SQL Redshift 中对表进行分区后比较两列的值

mysql之表分区

mysql表分区使用及详细介绍

如何在 SnappyData 中对列表中的数据进行分区?