• 首页
  • vue
  • TypeScript
  • JavaScript
  • scss
  • css3
  • html5
  • php
  • MySQL
  • redis
  • jQuery
  • MERGE存储引擎

    MERGE存储引擎,也被称为MRG_MyISAM发动机,是相同的集合MyISAM可被用作一个表。“相同”表示所有表具有相同的列数据类型和索引信息。您不能合并MyISAM以不同顺序列出列的表,在相应列中没有完全相同的数据类型或以不同顺序索引的表。但是,MyISAM可以使用myisampack压缩任何或所有表。请参见“myisampack-生成压缩的只读MyISAM表”。诸如此类的表之间的差异无关紧要:

    • 相应列和索引的名称可以不同。
    • 表,列和索引的注释可以不同。
    • 表的选项,如AVG_ROW_LENGTHMAX_ROWSPACK_KEYS可以不同。

    MERGE表的替代方法是分区表,该表将单个表的分区存储在单独的文件中,并使某些操作可以更有效地执行。有关更多信息,请参见分区

    创建MERGE表时,MySQL .MRG在磁盘上创建一个文件,该文件包含MyISAM应该用作一个表的基础表的名称。表的表格式MERGE存储在MySQL数据字典中。基础表不必与MERGE表位于同一数据库中。

    您可以使用SELECTDELETEUPDATE,和INSERTMERGE表。您必须在映射到表的表上具有SELECTDELETEUPDATE特权。MyISAMMERGE

    注意

    使用MERGE表会带来以下安全问题:如果用户有权访问MyISAMt,则该用户可以创建一个访问的MERGE表。但是,如果用户的权限在随后撤销,用户可以继续访问通过这样做。mtttm

    DROP TABLEMERGE表一起使用仅会丢弃MERGE规范。基础表不受影响。

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

    以下示例显示如何创建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索引为a ,但在表中未索引。在那里对其进行了索引,但没有将其作为索引,因为表无法在基础表的集合上强制唯一性。(类似地,在基础表中具有索引的列应在表中建立索引,但不能作为索引。)PRIMARY KEYMyISAMMERGEPRIMARY KEYMERGEUNIQUEMERGEUNIQUE

    创建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_name UNION=(...)

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

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

    • 基础表和MERGE表必须具有相同的列数。
    • 基础表和MERGE表中的列顺序必须匹配。
    • 此外,将对父MERGE表和基础表中每个对应列的规范进行比较,并且必须满足以下检查条件:

      • 基础表和MERGE表中的列类型必须相等。
      • 基础表和MERGE表中的列长度必须相等。
      • 基础表和MERGE表的列可以是NULL
    • 基础表必须至少具有与MERGE表一样多的索引。基础表可能比该MERGE表具有更多索引,但不能更少。

      注意

      存在一个已知的问题,即在MERGE表和基础MyISAM表中,同一列上的索引必须具有相同的顺序。参见错误#33653。

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

      • 基础表和MERGE表的索引类型必须相同。
      • 基础表和MERGE表的索引定义中的索引部分(即,复合索引中的多个列)的数目必须相同。
      • 对于每个索引部分:

        • 索引部件的长度必须相等。
        • 索引零件类型必须相等。
        • 索引零件语言必须相等。
        • 检查分度是否可以NULL

    如果MERGE由于基础表存在问题而无法打开或使用表,则CHECK TABLE显示有关引起问题的表的信息。

    MERGE表的优缺点

    MERGE表可以帮助您解决以下问题:

    • 轻松管理一组日志表。例如,您可以将不同月份的数据放入单独的表中,使用myisampack压缩其中的一些数据,然后创建一个MERGE表以将它们用作一个表。
    • 获得更高的速度。您可以根据某些条件拆分一个大型只读表,然后将各个表放在不同的磁盘上。以MERGE这种方式构造的表可能比使用单个大表要快得多。
    • 执行更有效的搜索。如果您确切知道要查找的内容,则可以仅在基础表之一中搜索某些查询,而MERGE在其他表中使用该表。您甚至可以拥有许多MERGE使用重叠表集的不同表。
    • 执行更有效的维修。修复映射到MERGE表的单个较小的表比修复单个大表要容易。
    • 立即将多个表映射为一个。一个MERGE表不需要维护自己的索引,因为它使用了各个表的索引。因此,MERGE表集合的创建或重新映射速度非常快。(MERGE即使没有创建索引,在创建表时仍必须指定索引定义。)
    • 如果您有一组表,可以根据需要从中创建一个大表,则可以根据需要从中创建一个MERGE表。这快得多,并节省了大量磁盘空间。
    • 超出操作系统的文件大小限制。每个MyISAM表都有此限制,但MyISAM表的集合则不受此限制。
    • 您可以MyISAM通过定义MERGE映射到单个表的表来为表创建别名或同义词。这样做不会对性能造成任何明显的影响(memcpy()每次读取仅两次间接调用和调用)。

    MERGE表的缺点是:

    • MyISAM一个MERGE表只能使用相同的表。
    • 某些MyISAM功能在MERGE表格中不可用。例如,您不能FULLTEXTMERGE表上创建索引。(您可以FULLTEXT在基础MyISAM表上创建索引,但是不能MERGE使用全文本搜索来搜索表。)
    • 如果MERGE表是非临时表,则所有基础MyISAM表都必须是非临时表。如果MERGE表是临时表,则MyISAM表可以是临时表和非临时表的任意组合。
    • MERGE表使用的文件描述符比MyISAM表更多。如果10个客户端使用的MERGE表映射到10个表,则服务器使用(10×10)+ 10个文件描述符。(10个客户端中的每个客户端都有10个数据文件描述符,客户端之间共享10个索引文件描述符。)
    • 索引读取速度较慢。当您读取索引时,MERGE存储引擎需要对所有基础表发出读取,以检查哪个表最匹配给定索引值。为了读取下一个索引值,MERGE存储引擎需要搜索读取的缓冲区以找到下一个值。仅当一个索引缓冲区用完时,存储引擎才需要读取下一个索引块。这会使MERGE索引在eq_ref搜索时慢很多,但在搜索时却不会慢很多ref。有关详细信息eq_ref,并ref请参见第13.8.2,“EXPLAIN语句”。

    合并表问题

    以下是MERGE表的已知问题:

    • 在5.1.23之前的MySQL Server版本中,可以使用非临时子MyISAM表创建临时合并表。

      从5.1.23版开始,MERGE子级通过父表被锁定。如果父母是临时的,则它不会被锁定,因此孩子也不会被锁定。MyISAM表的并行使用损坏了它们。

    • 如果用于ALTER TABLEMERGE表更改为另一个存储引擎,则到基础表的映射将丢失。取而代之的是,将基础MyISAM表中的行复制到更改后的表中,该表随后使用指定的存储引擎。
    • INSERT_METHOD一个表选择MERGE表指示哪个底层MyISAM使用表插入到MERGE表中。但是,对该AUTO_INCREMENT表使用 table选项对MyISAM插入表无效,MERGE直到至少有一行直接插入到表中为止MyISAM
    • 一个MERGE表不能在整个表上维护唯一性约束。当执行时INSERT,数据进入第一个或最后一个MyISAM表(由INSERT_METHOD选项确定)。MySQL确保唯一键值在该MyISAM表中保持唯一,但在整个集合的所有基础表中均不唯一。
    • 由于MERGE引擎无法对基础表集实施唯一性,因此REPLACE无法按预期工作。两个关键事实是:

      • REPLACE只能在要写入的基础表中检测唯一键冲突(由INSERT_METHOD选项决定)。这与MERGE表本身中的冲突不同。
      • 如果REPLACE检测到唯一键冲突,它将仅更改其要写入的基础表中的相应行;即由INSERT_METHOD选项确定的第一个或最后一个表。

      类似的考虑也适用INSERT ... ON DUPLICATE KEY UPDATE

    • MERGE表不支持分区。也就是说,您不能对MERGE表进行分区,也不能对MERGE表的任何基础MyISAM表进行分区。
    • 你不应该使用ANALYZE TABLEREPAIR TABLEOPTIMIZE TABLEALTER TABLEDROP TABLEDELETE没有一个WHERE条款,或TRUNCATE TABLE任何被映射到一个开放的表的MERGE表。如果这样做,该MERGE表仍可能引用原始表,并且会产生意外的结果。要变通解决此问题,MERGE通过FLUSH TABLES执行任何命名的操作之前发出一条语句,确保没有表保持打开状态。

      意外的结果包括对MERGE表的操作将报告表损坏的可能性。如果这在基础MyISAM表上的命名操作之一之后发生,则损坏消息是虚假的。为了解决这个问题,请FLUSH TABLES在修改MyISAM表后发出一条语句。

    • DROP TABLE在表上使用的MERGE表在Windows上不起作用,因为MERGE存储引擎的表映射是从MySQL的上层隐藏的。Windows不允许删除打开的文件,因此您必须先删除所有MERGE表(使用FLUSH TABLES)或删除MERGE表,然后再删除表。
    • 访问表时(例如,作为or 语句的一部分)检查MyISAM表的定义和MERGE表。这些检查通过比较列顺序,类型,大小和关联的索引来确保表的定义与父表的定义匹配。如果表之间存在差异,则返回错误,并且语句失败。因为这些检查是在打开表时进行的,所以对单个表的定义的任何更改(包括列更改,列顺序和引擎更改)都将导致语句失败。SELECTINSERTMERGE
    • MERGE表及其基础表中索引的顺序应相同。如果用于ALTER TABLEUNIQUE表中使用的MERGE表添加索引,然后用于在表ALTER TABLE上添加非MERGE唯一索引,则在基础表中已经存在非唯一索引的情况下,表的索引顺序会有所不同。(发生这种情况是因为ALTER TABLEUNIQUE索引放在非唯一索引之前,以便于快速检测重复键。)因此,对具有此类索引的表的查询可能会返回意外结果。
    • 如果遇到类似于错误1017(HY000)tbl_name的错误消息:找不到文件:'. MRG'(errno:2),则通常表明某些基础表未使用MyISAM存储引擎。确认所有这些表都是MyISAM
    • 表中的最大行数MERGE为2 64(〜1.844E + 19;与MyISAM表相同)。无法将多个MyISAM表合并为一个MERGE具有多于此行数的表。
    • 当前已知将MyISAM不同行格式的基础表与父MERGE表一起使用会失败。请参阅错误#32364。
    • 有效时,您无法更改非临时MERGE表的联合列表LOCK TABLES。以下就不能正常工作:

      CREATE TABLE m1 ... ENGINE=MRG_MYISAM ...;
      LOCK TABLES t1 WRITE, t2 WRITE, m1 WRITE;
      ALTER TABLE m1 ... UNION=(t1,t2) ...;
      

      但是,您可以使用临时MERGE表来执行此操作。

    • 您不能MERGE使用CREATE ... SELECT,临时MERGE表和非临时表创建MERGE表。例如:

      CREATE TABLE m1 ... ENGINE=MRG_MYISAM ... SELECT ...;
      

      尝试执行此操作会导致错误:tbl_name不是BASE TABLE

    • 在某些情况下,如果基础表包含或列,则基础表和基础表PACK_KEYS之间的表选项值不同MERGE会导致意外结果。解决方法是,用于确保所有涉及的表都具有相同的值。错误35646)CHARBINARYALTER TABLEPACK_KEYS