Related Documentation Download this Manual
PDF (US Ltr) - 39.8Mb
PDF (A4) - 39.9Mb
Man Pages (TGZ) - 257.9Kb
Man Pages (Zip) - 364.9Kb
Info (Gzip) - 4.0Mb
Info (Zip) - 4.0Mb


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

18.7 MERGE 存储引擎

MERGE 存储引擎,也称为 MRG_MyISAM 引擎,是一组相同的 MyISAM 表,可以用作一个。这里的“相同”意味着所有表都具有相同的列数据类型和索引信息。你不能将 MyISAM 表合并,其中列顺序不同、对应列的数据类型不同或索引顺序不同。但是,你可以使用 myisampack 将任意或所有 MyISAM 表压缩。请参阅 第6.6.6节,“myisampack — Generate Compressed, Read-Only MyISAM Tables”。以下情况不影响表的合并:

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

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

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

MERGE表的替代方案是分区表,它将单个表的分区存储在不同的文件中,并启用一些操作可以更高效地进行。更多信息,请见第26章,分区

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

您可以对MERGE表执行SELECTDELETEUPDATEINSERT。您必须在映射到MERGE表的MyISAM表上拥有SELECTDELETEUPDATE权限。

Note

使用MERGE表格存在以下安全问题:如果用户有访问MyISAMt的权限,那么该用户可以创建一个访问tMERGEm。然而,如果用户对t的权限随后被撤销,那么该用户仍然可以通过m访问t

使用DROP TABLE命令删除MERGE表格时,只会删除MERGE表格的定义,而不会影响 underlying 表。

要创建一个MERGE表格,您需要指定一个UNION=(list-of-tables)选项,该选项指明使用哪些MyISAM表。您可以选择性地指定一个INSERT_METHOD选项,以控制对MERGE表格的插入操作。使用FIRSTLAST值来使插入操作在第一个或最后一个 underlying 表中进行。如果您没有指定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;

在 underlying MyISAM 表中,列a被索引为PRIMARY KEY,但是在MERGE表中,它被索引,但是不是作为PRIMARY KEY,因为MERGE表不能在 underlying 表集中强制唯一性。类似地,在 underlying 表中具有UNIQUE索引的列,在MERGE表中也需要索引,但是不是作为UNIQUE索引。

创建了MERGE表后,您可以使用它来对组合表进行查询操作:

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

要将MERGE表 remap 到不同的MyISAM表集合,可以使用以下方法之一:

  • DROP MERGE 表并重新创建它。

  • 使用ALTER TABLE tbl_名 UNION=(...)更改 underlying 表的列表。

    还可以使用ALTER TABLE ... UNION=()(即空的UNION子句)将所有 underlying 表删除。然而,在这种情况下,表实际上是空的,并且插入操作失败,因为没有 underlying 表来接收新行。这种表可能作为创建新的MERGE表模板,以CREATE TABLE ... LIKE语句创建新的MERGE表。

底层表定义和索引必须紧密地遵守MERGE表的定义。检查是在打开作为MERGE表的一部分的表时进行的,而不是在创建MERGE表时。如果任何表无法通过检查,触发该操作的操作将失败。这意味着对MERGE表中的表定义的更改可能会导致访问MERGE表时的失败。对每个表进行的检查是:

  • 底层表和MERGE表必须具有相同的列数。

  • 底层表和MERGE表中的列顺序必须匹配。

  • 此外,对于每个对应列在父MERGE表和底层表的指定进行比较,并且必须满足这些检查:

    • 底层表和MERGE表中的列类型必须相等。

    • 底层表和MERGE表中的列长度必须相等。

    • 底层表和MERGE表中的列可以是NULL

  • 底层表必须至少具有与MERGE表相同的索引。底层表可能具有更多的索引,但不能少于。

    Note

    已知的问题是,同一列上的索引在MERGE表和底层MyISAM表中必须具有相同的顺序。请参阅Bug #33653。

    每个索引都必须满足这些检查:

    • 底层表和MERGE表的索引类型必须相同。

    • 底层表和MERGE表的索引定义中索引部分(即多个列在复合索引中的组成)的数量必须相同。

    • 对于每个索引部分:

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

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

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

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

如果MERGE表无法打开或使用,因为底层表存在问题,CHECK TABLE将显示关于哪个表引起问题的信息。