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
表集合,可以使用以下方法:
-
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
将显示导致问题的表的信息。
附加资源
-
有一个专门的
MERGE
存储引擎论坛,位于 https://forums.mysql.com/list.php?93。