MERGE 存储引擎,也称为 MRG_MyISAM 引擎,是一组相同的 MyISAM 表,可以作为一个表使用。 “相同” 表示所有表具有相同的列数据类型和索引信息。您无法合并列顺序不同、对应列中数据类型不完全相同或索引顺序不同的 MyISAM 表。但是,可以使用 myisampack 压缩任何或所有 MyISAM 表。请参见 第 6.6.6 节,“myisampack — 生成压缩的只读 MyISAM 表”。这些表之间的差异无关紧要
对应列和索引的名称可以不同。
表、列和索引的注释可以不同。
表选项(如
AVG_ROW_LENGTH、MAX_ROWS或PACK_KEYS)可以不同。
与 MERGE 表的替代方案是分区表,它将单个表的分区存储在单独的文件中,并使某些操作能够更高效地执行。有关更多信息,请参见 第 26 章,分区。
创建 MERGE 表时,MySQL 会在磁盘上创建一个 .MRG 文件,其中包含应作为一个表使用的基础 MyISAM 表的名称。MERGE 表的表格式存储在 MySQL 数据字典中。基础表不必与 MERGE 表位于同一个数据库中。
您可以在 MERGE 表上使用 SELECT、DELETE、UPDATE 和 INSERT。您必须对映射到 MERGE 表的 MyISAM 表拥有 SELECT、DELETE 和 UPDATE 权限。
使用 MERGE 表会带来以下安全问题:如果用户可以访问 MyISAM 表 t,则该用户可以创建一个访问 t 的 MERGE 表 m。但是,如果该用户的 t 权限随后被撤销,则该用户可以通过 m 继续访问 t。
使用 DROP TABLE 与 MERGE 表一起使用,只会删除 MERGE 规范。基础表不受影响。
要创建 MERGE 表,您必须指定一个 UNION=( 选项,该选项指示要使用的哪些 list-of-tables)MyISAM 表。您还可以选择指定 INSERT_METHOD 选项来控制对 MERGE 表的插入操作。使用 FIRST 或 LAST 值会导致分别在第一个或最后一个基础表中进行插入。如果未指定 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 表中没有被索引。在那里,它被索引,但不是 PRIMARY KEY,因为 MERGE 表无法在基础表集中强制唯一性。(类似地,在基础表中具有 UNIQUE 索引的列应该在 MERGE 表中被索引,但不能作为 UNIQUE 索引。)
创建 MERGE 表后,您可以使用它来发出对整个表组执行操作的查询
mysql> SELECT * FROM total;
+---+---------+
| a | message |
+---+---------+
| 1 | Testing |
| 2 | table |
| 3 | t1 |
| 1 | Testing |
| 2 | table |
| 3 | t2 |
+---+---------+要将 MERGE 表重新映射到不同的 MyISAM 表集合,您可以使用以下方法之一
DROPMERGE表并重新创建它。使用
ALTER TABLE更改基础表的列表。tbl_nameUNION=(...)也可以使用
ALTER TABLE ... UNION=()(即,使用空UNION子句)来删除所有基础表。但是,在这种情况下,表实际上是空的,插入操作会失败,因为没有基础表可以接收新行。这样的表可能有用,因为可以使用CREATE TABLE ... LIKE创建具有相同结构的新的MERGE表。
基础表的定义和索引必须与 MERGE 表的定义非常一致。当打开属于 MERGE 表的表时,会检查一致性,而不是在创建 MERGE 表时检查。如果任何表未能通过一致性检查,则触发该表打开的操作会失败。这意味着更改 MERGE 中表的定义可能会在访问 MERGE 表时导致失败。应用于每个表的符合性检查如下
基础表和
MERGE表必须具有相同数量的列。基础表和
MERGE表中的列顺序必须匹配。此外,还会比较父
MERGE表和基础表中每个对应列的规范,并且必须满足以下检查基础表和
MERGE表中的列类型必须相等。基础表和
MERGE表中的列长度必须相等。基础表和
MERGE表的列可以为NULL。
基础表必须至少拥有与
MERGE表一样多的索引。基础表可能比MERGE表拥有更多索引,但不能拥有更少的索引。注意存在一个已知问题,即相同列上的索引在
MERGE表和基础MyISAM表中都必须按相同的顺序。请参见 Bug #33653。每个索引必须满足以下检查
基础表和
MERGE表的索引类型必须相同。索引定义中索引部分(即复合索引内的多个列)的数量在基础表和
MERGE表中必须相同。对于每个索引部分
索引部分长度必须相等。
索引部分类型必须相等。
索引部分语言必须相等。
检查索引部分是否可以为
NULL。
如果由于基础表存在问题而无法打开或使用 MERGE 表,则 CHECK TABLE 会显示有关导致问题的表的相关信息。
其他资源
专门针对
MERGE存储引擎的论坛可在 https://forums.mysql.com/list.php?93 访问。