Related Documentation Download this Manual
PDF (US Ltr) - 40.8Mb
PDF (A4) - 40.9Mb
Man Pages (TGZ) - 294.0Kb
Man Pages (Zip) - 409.0Kb
Info (Gzip) - 4.0Mb
Info (Zip) - 4.0Mb
Excerpts from this Manual

MySQL 8.3 Reference Manual  /  Alternative Storage Engines  /  The MERGE Storage Engine

18.7 MERGE 存储引擎

MERGE 存储引擎,也称为 MRG_MyISAM 引擎,是一组相同的 MyISAM 表,可以作为一个表使用。“相同” 表示所有表具有相同的列数据类型和索引信息。你不能合并列顺序不同的 MyISAM 表,或者数据类型不同的列,或者索引顺序不同的表。然而,任何或所有 MyISAM 表都可以使用 myisampack 进行压缩。见 第 6.6.6 节,“myisampack — 生成压缩的、只读的 MyISAM 表”。表之间的差异,如下所示,不重要:

  • 对应列和索引的名称可以不同。

  • 表、列和索引的注释可以不同。

  • 表选项,如 AVG_ROW_LENGTHMAX_ROWSPACK_KEYS 可以不同。

MERGE 表的一个替代方案是分区表,它将单个表的分区存储在单独的文件中,并使某些操作更加高效。更多信息,请参见 第 26 章 分区

当你创建一个 MERGE 表时,MySQL 在磁盘上创建一个 .MRG 文件,该文件包含了要作为一个表使用的底层 MyISAM 表的名称。MERGE 表的表格式存储在 MySQL 数据字典中。底层表不需要与 MERGE 表在同一个数据库中。

你可以在 MERGE 表上使用 SELECTDELETEUPDATEINSERT。你必须拥有 SELECTDELETEUPDATE 权限在要映射到 MERGE 表的 MyISAM 表上。

Note

使用 MERGE 表会引发以下安全问题:如果用户拥有 MyISAM 表 t 的访问权限,那么该用户可以创建一个 MERGE 表 m,该表访问 t。然而,如果用户在 t 上的权限被撤销,该用户仍然可以通过 m 访问 t

使用 DROP TABLE 删除 MERGE 表时,只删除 MERGE 规格。底层表不受影响。

要创建 MERGE 表,你必须指定一个 UNION=(表列表) 选项,指示哪些 MyISAM 表要使用。你可以选择性地指定一个 INSERT_METHOD 选项,以控制插入 MERGE 表时的行为。使用 FIRSTLAST 值来使插入发生在第一个或最后一个底层表中。如果你没有指定 INSERT_METHOD 选项或指定它的值为 NO,那么插入 MERGE 表将不被允许,并且尝试这样做将导致错误。

以下示例显示如何创建一个 MERGE 表:

mysql> CREATE TABLE t1 (
    ->    a INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
    ->    message CHAR(20)) ENGINE=MyISAM;
mysql> CREATE TABLE t2 (
    ->    a INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
    ->    message CHAR(20)) ENGINE=MyISAM;
mysql> INSERT INTO t1 (message) VALUES ('Testing'),('table'),('t1');
mysql> INSERT INTO t2 (message) VALUES ('Testing'),('table'),('t2');
mysql> CREATE TABLE total (
    ->    a INT NOT NULL AUTO_INCREMENT,
    ->    message CHAR(20), INDEX(a))
    ->    ENGINE=MERGE UNION=(t1,t2) INSERT_METHOD=LAST;

a 在基础 MyISAM 表中被索引为 PRIMARY KEY,但是在 MERGE 表中不是这样索引的,因为 MERGE 表不能在基础表集合上强制唯一性。(类似地,在基础表中的唯一索引列在 MERGE 表中索引,但不是唯一索引。)

创建 MERGE 表后,可以使用它来执行在整个表组上的查询:

mysql> SELECT * FROM total;
+---+---------+
| a | message |
+---+---------+
| 1 | Testing |
| 2 | table   |
| 3 | t1      |
| 1 | Testing |
| 2 | table   |
| 3 | t2      |
+---+---------+

要将 MERGE 表重新映射到不同的 MyISAM 表集合,可以使用以下方法:

  • DROP MERGE 表并重新创建它。

  • 使用 ALTER TABLE tbl_name UNION=(...) 更改基础表列表。

    也可以使用 ALTER TABLE ... UNION=()(即,带有空 UNION 子句)删除所有基础表。在这种情况下,表将变为空,并且插入将失败,因为没有基础表来接受新行。这样的表可能作为创建新 MERGE 表的模板,使用 CREATE TABLE ... LIKE

基础表定义和索引必须与 MERGE 表定义非常相似。符合性检查是在表打开时进行的,而不是在创建 MERGE 表时。如果任何表失败了符合性检查,那么触发表打开的操作将失败。这意味着,MERGE 表中的表定义更改可能会在访问 MERGE 表时导致失败。对每个表应用的符合性检查是:

  • 基础表和 MERGE 表必须具有相同的列数。

  • 基础表和 MERGE 表中的列顺序必须匹配。

  • 此外,对于每个相应的列,父 MERGE 表和基础表的规范将被比较,并且必须满足以下检查:

    • 基础表和 MERGE 表中的列类型必须相等。

    • 基础表和 MERGE 表中的列长度必须相等。

    • 基础表和 MERGE 表中的列可以是 NULL

  • 基础表必须至少具有与 MERGE 表相同数量的索引。基础表可以具有比 MERGE 表更多的索引,但不能少于。

    Note

    已知的问题是,相同列上的索引必须在 MERGE 表和基础 MyISAM 表中以相同的顺序出现。见 Bug #33653。

    每个索引必须满足以下检查:

    • 基础表和 MERGE 表中的索引类型必须相同。

    • 基础表和 MERGE 表中的索引部分数量(即复合索引中的多个列)必须相同。

    • 对于每个索引部分:

      • 索引部分长度必须相等。

      • 索引部分类型必须相等。

      • 索引部分语言必须相等。

      • 检查索引部分是否可以是 NULL

如果 MERGE 表无法打开或使用,因为基础表存在问题,CHECK TABLE 将显示导致问题的表的信息。

附加资源