MERGE 存储引擎,也称为 MRG_MyISAM 引擎,是一组相同的 MyISAM 表,可以作为一个表使用。“相同” 表示所有表具有相同的列数据类型和索引信息。你不能合并列顺序不同的 MyISAM 表,或者数据类型不同的列,或者索引顺序不同的表。然而,任何或所有 MyISAM 表都可以使用 myisampack 进行压缩。见 第 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。你必须拥有 SELECT、DELETE 和 UPDATE 权限在要映射到 MERGE 表的 MyISAM 表上。
使用 MERGE 表会引发以下安全问题:如果用户拥有 MyISAM 表 t 的访问权限,那么该用户可以创建一个 MERGE 表 m,该表访问 t。然而,如果用户在 t 上的权限被撤销,该用户仍然可以通过 m 访问 t。
使用 DROP TABLE 删除 MERGE 表时,只删除 MERGE 规格。底层表不受影响。
要创建 MERGE 表,你必须指定一个 UNION=( 选项,指示哪些 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 表中不是这样索引的,因为 MERGE 表不能在基础表集合上强制唯一性。(类似地,在基础表中的唯一索引列在 MERGE 表中索引,但不是唯一索引。)
创建 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子句)删除所有基础表。在这种情况下,表将变为空,并且插入将失败,因为没有基础表来接受新行。这样的表可能作为创建新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 将显示导致问题的表的信息。
附加资源
-
有一个专门的
MERGE存储引擎论坛,位于 https://forums.mysql.com/list.php?93。