## 16.7 MERGE 存储引擎

[16.7.1 MERGE 表的优缺点](merge-table-advantages.html)
[16.7.2 合并表问题](merge-table-problems.html)

[](<>)[](<>)[](<>)[](<>)[](<>)

这`合并`存储引擎，也称为`MRG_MyISAM`引擎，是相同的集合`MyISAM`可以作为一张桌子使用。“相同”意味着所有表都具有相同的列数据类型和索引信息。你不能合并`MyISAM`列以不同顺序列出的表，对应列中的数据类型不完全相同，或者索引的顺序不同。然而，任何或所有`MyISAM`表可以压缩[**myisampack**](myisampack.html).看[第 4.6.6 节，“myisampack - 生成压缩的只读 MyISAM 表”](myisampack.html).诸如此类的表之间的差异无关紧要：

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

-   表、列和索引的注释可能不同。

-   表选项，例如`AVG_ROW_LENGTH`,`MAX_ROWS`， 要么`PACK_KEYS`可以不同。

    一个替代品`合并`table 是一个分区表，它将单个表的分区存储在单独的文件中，并使某些操作能够更有效地执行。有关详细信息，请参阅[第 24 章，*分区*](partitioning.html).

    当你创建一个`合并`表，MySQL 创建一个`.MRG`磁盘上包含底层证券名称的文件`MyISAM`应该作为一个表使用。表格的格式`合并`表存储在 MySQL 数据字典中。基础表不必与`合并`桌子。

    您可以使用[`选择`](select.html),[`删除`](delete.html),[`更新`](update.html)， 和[`插入`](insert.html)在`合并`表。你必须有[`选择`](privileges-provided.html#priv_select),[`删除`](privileges-provided.html#priv_delete)， 和[`更新`](privileges-provided.html#priv_update)上的特权`MyISAM`您映射到的表`合并`桌子。

笔记

指某东西的用途`合并`表会带来以下安全问题：如果用户有权访问`MyISAM`桌子*`吨`*，该用户可以创建一个`合并`桌子*`米`*访问*`吨`*.但是，如果用户的权限*`吨`*随后被撤销，用户可以继续访问*`吨`*通过这样做*`米`*.

用于[`删除表`](drop-table.html)与`合并`表只删除`合并`规格。基础表不受影响。

创建一个`合并`表，您必须指定一个`联合=（*`表列表`*)`指示哪个选项`MyISAM`要使用的表。您可以选择指定一个`插入方法`控制如何插入的选项`合并`表发生。使用值`第一的`要么`最后的`分别在第一个或最后一个基础表中进行插入。如果您指定否`插入方法`选项，或者如果您将其指定为`不`, 插入`合并`table 是不允许的，尝试这样做会导致错误。

下面的例子展示了如何创建一个`合并`桌子：

```
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;
```

柱子`一种`被索引为`首要的关键`在底层`MyISAM`表，但不在`合并`桌子。在那里它被索引但不是作为`首要的关键`因为一个`合并`table 不能对一组基础表强制唯一性。（类似地，一列带有`独特`基础表中的索引应在`合并`表但不作为`独特`指数。）

创建后`合并`表，您可以使用它来发出对整个表组进行操作的查询：

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

重新映射一个`合并`表到不同的集合`MyISAM`表，您可以使用以下方法之一：

-   `降低`这`合并`表并重新创建它。

-   采用`更改表 *`tbl_name`* 联合=(...)`更改基础表的列表。

    也可以使用`更改表 ... UNION=()`（也就是说，有一个空的[`联盟`](union.html)子句）删除所有基础表。但是，在这种情况下，表实际上是空的并且插入失败，因为没有基础表来获取新行。这样的表可能可用作创建新表的模板`合并`表[`创建表...喜欢`](create-table-like.html).

    基础表定义和索引必须与`合并`桌子。当表属于`合并`表被打开，而不是当`合并`表已创建。如果任何表未通过一致性检查，则触发打开表的操作将失败。这意味着更改一个内表的定义`合并`可能会导致失败时`合并`表被访问。应用于每个表的一致性检查是：

-   基础表和`合并`表必须具有相同的列数。

-   基础表中的列顺序和`合并`表必须匹配。

-   此外，父中每个对应列的规范`合并`表和基础表进行比较，并且必须满足以下检查：

    -   基础表中的列类型和`合并`表必须相等。

    -   基础表中的列长度和`合并`表必须相等。

    -   基础表的列和`合并`表可以`空值`.

-   基础表的索引必须至少与`合并`桌子。基础表的索引可能比`合并`表，但不能少。

    笔记

    存在一个已知问题，即相同列上的索引必须以相同的顺序排列，在`合并`表和底层证券`MyISAM`桌子。请参阅错误 #33653。

    每个索引必须满足以下检查：

    -   基础表的索引类型和`合并`表必须相同。

    -   基础表的索引定义中的索引部分（即复合索引中的多个列）的数量和`合并`表必须相同。

    -   对于每个索引部分：

        -   索引部分的长度必须相等。

        -   索引部分类型必须相同。

        -   索引部分语言必须相同。

        -   检查索引部分是否可以`空值`.

    如果一个`合并`由于基础表存在问题，无法打开或使用表，[`检查表`](check-table.html)显示有关哪个表导致问题的信息。

### 其他资源

-   一个专门的论坛`合并`存储引擎可在<https://forums.mysql.com/list.php?93>.
