MySQL 中的分区是什么?

2025年03月17日 | 阅读 9 分钟

MySQL 中的分区用于将表中的行分割或分区到不同位置的独立表中,但仍然将其视为单个表。它根据我们设定的规则,将表数据的一部分分发到文件系统中。我们为实现表数据划分而设定的规则称为分区函数(模数、线性或内部哈希函数等)。选定的函数基于我们指定的分区类型,并接受用户提供的表达式作为其参数。用户表达式可以是列值,也可以是作用于列值的函数,具体取决于所使用的分区类型。

MySQL 8.0 只支持 InnoDB 和 NDB 存储引擎的分区。其他存储引擎如 MyISAM、MERGE、CSV 和 FEDERATED 不支持分区。

MySQL 主要有两种分区形式

1. 水平分区

这种分区根据我们的逻辑将表的行分割成多个表。在水平分区中,每个表中的列数相同,但行数不必相同。它在物理上分割表,但在逻辑上被视为一个整体。目前,MySQL 只支持这种分区。

2. 垂直分区

这种分区将表分割成多个表,其中包含原始表中较少的列。它使用一个附加表来存储剩余的列。目前,MySQL 不支持这种分区。

分区的优势

以下是在 MySQL 中进行分区的好处:

  • 它优化了查询性能。当我们查询表时,它只扫描满足特定语句的部分表。
  • 可以在一个表中存储大量数据,这些数据可以保存在单个磁盘或文件系统分区中。
  • 它提供了对数据库数据进行管理的更多控制。

如何在 MySQL 中分区表?

我们可以使用 CREATE TABLEALTER TABLE 语句 在 MySQL 中创建分区。以下是使用 CREATE TABLE 命令创建分区的语法


以下是使用 ALTER TABLE 命令创建分区的语法

MySQL 分区类型

MySQL 主要有六种分区类型,如下所示:

  1. RANGE 分区
  2. LIST 分区
  3. COLUMNS 分区
  4. HASH 分区
  5. KEY 分区
  6. 子分区

让我们详细讨论每种分区。

MySQL RANGE 分区

这种分区允许我们根据落在指定范围内的列值来分区表的行。给定的范围始终是连续的,但不应重叠,并且使用 VALUES LESS THAN 操作符来定义范围。

在下面的示例中,我们将创建一个名为 "Sales" 的表,其中包含 cust_id、name、store_id、bill_no、bill_date 和 amount 五列。接下来,我们将根据我们的需求以多种方式使用范围来分区此表。在这里,我们将使用 bill_date 列进行分区,然后使用 PARTITION BY RANGE 子句将表的数据分成四部分。

接下来,我们需要插入如下语句所示的记录到表中

要验证记录,我们将执行以下语句

我们可以看到记录已成功插入到 Sales 表中。

MySQL Partitioning

我们可以使用以下查询查看 CREATE TABLE 语句创建的分区

我们将得到以下输出,其中四个分区已成功创建

MySQL Partitioning

删除 MySQL 分区

有时我们的表中包含分区表中无用的数据。在这种情况下,我们可以根据需要删除单个或多个分区。以下语句用于删除 Sales 表的 partition p0 中的所有行

成功执行后,我们可以看到表中删除了两条记录。

MySQL Partitioning

我们可以使用以下查询验证分区表

在输出中,我们可以看到分区 p0 不包含任何行。

MySQL Partitioning

MySQL LIST 分区

它与 Range Partitioning 相同。这里,分区基于列匹配一组离散值列表而不是一组连续值范围来定义和选择。它通过 PARTITION BY LIST(exp) 子句执行。exp 是返回整数值的表达式或列值。VALUES IN(value_lists) 语句将用于定义每个分区。

在下面的示例中,假设我们有 12 个商店,根据地区分布在四个特许经营商中。下表更清楚地说明了这一点

地区商店 ID 号
101, 103, 105
西102, 104, 106
北部107, 109, 111
108, 110, 112

我们可以对上述表进行分区,其中属于同一地区的商店的行将存储在同一个分区中。以下语句使用 LIST 分区将同一地区的商店分组,如下所示:

成功执行后,它将给出以下输出;

MySQL Partitioning

MySQL HASH 分区

此分区用于基于 **预定义数量** 的分区来分发数据。换句话说,它根据用户定义的表达式返回的值来分割表。它主要用于将数据均匀地分布到分区中。它通过 PARTITION BY HASH(expr) 子句执行。在这里,我们可以根据 column_name 指定一个要哈希的列值以及表被分割的分区数量。

此语句用于使用 CREATE TABLE 命令创建表 Store,并对 store_id 列使用哈希,将其分成四个分区。

注意:如果您不使用 PARTITIONS 子句,默认情况下分区数量将为一。如果您不使用 PARTITIONS 关键字指定数字,它将抛出错误。

MySQL COLUMN 分区

此分区允许我们在分区键中使用多个列。这些列的目的是将行放置在分区中,并确定哪个分区将匹配行。它主要分为两种类型:

  • RANGE Columns 分区
  • LIST Columns 分区

它们支持使用非整数列来定义范围或值列表。它们支持以下数据类型:

  • 所有整数类型: TINYINT、SMALLINT、MEDIUMINT、INT (INTEGER) 和 BIGINT。
  • 字符串类型: CHAR、VARCHAR、BINARY 和 VARBINARY。
  • DATE 和 DATETIME 数据类型。

Range Column 分区: 它与 range 分区类似,有一个区别。它使用基于各种列作为分区键的范围来定义分区。定义的范围是除整数类型之外的列类型。

以下是 Range Columns 分区的语法。

让我们通过以下示例来理解它。

在此示例中,表 "test_part" 包含 A、B、C 和 D 四列。我们按 A、B、C 的顺序在分区中使用前三列。并且,每个列表值用于定义一个包含三个值(按 INT、CHAR 和 INT 的顺序)的分区。执行后,我们将得到如下输出,并通过 SELECT 语句 成功验证。

MySQL Partitioning

List Columns 分区: 它接受单列或多列的列表作为分区键。它使我们能够使用非整数类型的各种列作为分区列。在此分区中,我们可以使用字符串数据类型、DATE 和 DATETIME 列。

以下示例更清楚地说明了这一点。假设一家公司有许多营销代理分布在三个城市。我们可以这样组织:

城市营销代理
纽约A1, A2, A3
德克萨斯州B1, B2, B3
加利福尼亚C1, C2, C3

以下语句使用 List Columns 分区来组织代理

成功执行后,我们将得到如下输出

MySQL Partitioning

MySQL KEY 分区

它类似于 HASH 分区,其中哈希分区使用用户指定的表达式,而 MySQL 服务器提供 KEY 的哈希函数。如果我们使用其他存储引擎,MySQL 服务器将使用其内部哈希函数,该函数通过 PARTITION BY KEY 子句执行。在这里,我们将使用 KEY 而不是 HASH,它只能接受零个或多个列名的列表。

如果表包含 PRIMARY KEY 并且我们没有指定任何用于分区的列,则主键将用作分区键。以下示例更清楚地说明了这一点。

如果表有唯一键但没有主键,那么 UNIQUE KEY 将用作分区键。

子分区

它是一种复合分区,用于进一步分割分区表中的每个分区。以下示例有助于我们更清楚地理解它。

执行以下语句以验证子分区

它将给出如下输出

MySQL Partitioning