15.7 MERGE 存储引擎

MERGE存储引擎(也称为MRG_MyISAM引擎)是相同的MyISAMtable 的集合,这些 table 可以用作一个 table。 “相同”table 示所有 table 具有相同的列数据类型和索引信息。您不能合并列以不同 Sequences 列出的MyISAMtable,对应列中的数据类型不完全相同或索引的 Sequences 不同。但是,可以使用myisampack压缩任何或所有MyISAMtable。参见第 4.6.5 节“ myisampack —生成压缩的只读 MyISAMtable”。诸如此类的 table 之间的差异无关紧要:

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

  • table,列和索引的 Comments 可以不同。

  • AVG_ROW_LENGTHMAX_ROWSPACK_KEYS之类的 table 选项可以不同。

MERGEtable 的替代方法是分区 table,该 table 将单个 table 的分区存储在单独的文件中。分区使某些操作可以更有效地执行,并且不限于MyISAM存储引擎。有关更多信息,请参见第 22 章,分区

创建MERGEtable 时,MySQL 在磁盘上创建两个文件。这些文件的名称以 table 名开头,并具有 extensions 以指示文件类型。 .frm文件存储 table 格式,而.MRG文件包含应作为基础的MyISAMtable 的名称。这些 table 不必与MERGEtable 位于同一数据库中。

您可以在MERGE个 table 上使用SELECTDELETEUPDATEINSERT。您必须在 Map 到MERGEtable 的MyISAMtable 上具有SELECTDELETEUPDATE特权。

Note

MERGEtable 的使用引起以下安全问题:如果用户有权访问MyISAMtable* t ,则该用户可以创建MERGEtable m 来访问 t 。但是,如果随后撤消了对 t 的用户特权,则用户可以通过 m continue 访问 t *。

DROP TABLEMERGEtable 一起使用只会删除MERGE规范。基础 table 不受影响。

要创建MERGEtable,必须指定UNION=(list-of-tables)选项,该选项指示要使用的MyISAMtable。您可以选择指定INSERT_METHOD选项,以控制如何插入MERGEtable。使用值FIRSTLAST分别导致在第一个或最后一个基础 table 中进行插入。如果您未指定INSERT_METHOD选项,或者您指定的值为NO,则不允许插入MERGEtable,并且尝试这样做会导致错误。

下面的示例演示如何创建MERGEtable:

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列在基础MyISAMtable 中索引为PRIMARY KEY,但在MERGEtable 中未索引。它在那里被索引但不是PRIMARY KEY,因为MERGEtable 不能对基础 table 集实施唯一性。 (类似地,基础 table 中具有UNIQUE索引的列应在MERGEtable 中构建索引,而不是UNIQUE索引.)

创建MERGEtable 后,您可以使用它发出对整个 table 组进行操作的查询:

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

要将MERGEtable 重新 Map 到MyISAMtable 的不同集合,可以使用以下方法之一:

  • DROP MERGEtable 并重新创建它。

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

也可以使用ALTER TABLE ... UNION=()(即带有空的UNION子句)来删除所有基础 table。但是,在这种情况下,该 table 实际上是空的,并且插入失败,因为没有基础 table 可以使用新行。这样的 table 作为用创建 table...喜欢创建新的MERGEtable 的模板可能有用。

基础 table 定义和索引必须紧密符合MERGEtable 的定义。当打开属于MERGEtable 的 table 时,而不是在创建MERGEtable 时,检查一致性。如果任何 table 未通过一致性检查,则触发打开 table 的操作将失败。这意味着在访问MERGEtable 时对MERGE中的 table 的定义进行更改可能会导致失败。应用于每个 table 的一致性检查是:

  • 基础 table 和MERGEtable 的列数必须相同。

  • 基础 table 和MERGEtable 中的列 Sequences 必须匹配。

  • 此外,将对父MERGEtable 和基础 table 中每个对应列的规范进行比较,并且必须满足以下检查条件:

  • 基础 table 和MERGEtable 中的列类型必须相等。

    • 基础 table 和MERGEtable 中的列长度必须相等。

    • 基础 table 和MERGEtable 的列可以是NULL

  • 基础 table 必须具有至少与MERGEtable 一样多的索引。基础 table 可能比MERGEtable 具有更多的索引,但不能更少。

Note

存在一个已知的问题,即在MERGEtable 和基础MyISAMtable 中,同一列上的索引必须具有相同的 Sequences。参见错误#33653.

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

  • 基础 table 和MERGEtable 的索引类型必须相同。

    • 基础 table 和MERGEtable 的索引定义中的索引部分(即,复合索引中的多个列)的数目必须相同。

    • 对于每个索引部分:

  • 索引部件的长度必须相等。

    • 索引 Component 类型必须相等。

    • 索引 Component 语言必须相等。

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

如果由于基础 table 存在问题而无法打开或使用MERGEtable,则CHECK TABLE显示有关哪个 table 导致问题的信息。

Additional Resources