MRG_MyISAM
エンジンとしても知られているMERGE
ストレージエンジンは、一つの物として使用する事ができる同一のMyISAM
テーブルの集まりです。「同一の」というのは、全てのテーブルが同一のカラムとインデックス情報を持つという意味です。カラムのリストされている順番が違っていたり、カラムが完全に一致していなかったり、インデックスの順番が違っていたりするとMyISAM
テーブルをマージする事はできません。しかし、全てのMyISAM
テーブルはmyisampackで圧縮する事ができます。詳しくは項7.6. 「myisampack — 圧縮された、読み取り専用MyISAM テーブルを作成する。」を参照してください。AVG_ROW_LENGTH
、
MAX_ROWS
、または PACK_KEYS
等のようなテーブルオプションの違いは問題ではありません。
MERGE
テーブルを作成する時、MySQLはディスク上に二つファイルを作成します。そのファイル名はテーブル名で始まり、ファイルタイプを指示する拡張子が付きます。.frm
ファイルはテーブルフォーマットを格納し、.MRG
ファイルは一つの物として使用されるべきテーブルの名前を含んでいます。それらのテーブルは、MERGE
テーブルそのものと同じデータベースになくてはならないという訳ではありません。
MERGE
テーブル上では、SELECT
、
DELETE
、 UPDATE
、そして
INSERT
を利用する事ができます。MERGE
テーブルにマップするMyISAM
テーブル上に、 SELECT
、
UPDATE
、そして DELETE
権限を持たなければいけません。
MERGE
テーブルの利用は、次のセキュリティに関する問題を引き起こします。ユーザが
MyISAM
テーブル
t
にアクセスする事ができる時、そのユーザは
t
にアクセスする事ができるMERGE
テーブル
m
を作成する事ができます。しかし、もしユーザのt
に対する特権が後で破棄されるなら、m
にアクセスする事でt
にアクセスし続ける事ができます。もしこの作業が好ましくなければ、MERGE
ストレージエンジンを無効にする為に、新しい--skip-merge
オプションを使ってサーバをスタートさせる事ができます。このオプションはMySQL
5.1.12.以降で利用できます。
MERGE
テーブルをDROP
する時、
MERGE
仕様だけが削除されます。
基礎となるテーブルは影響を受けません。
MERGE
テーブルを作成するには、どの
MyISAM
テーブルを一つの物として利用したいかを示すUNION=(
条項を指定しなければいけません。list-of-tables
)MERGE
テーブルに、 UNION
リストの最初か最後のテーブルに位置する為の挿入が必要であれば、自由に
INSERT_METHOD
オプションを指定する事ができます。テーブルの最初か最後に挿入されるように、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;
基礎となっている MyISAM
テーブルの中で、a
カラムはPRIMARY
KEY
としてインデックスされていますが、MERGE
テーブルの中ではそうではない事に注意してください。MERGE
テーブルは、基礎となるテーブルに対して一意性を実行することができないので、インデックスはされるのですが、それはPRIMARY
KEY
としてではないのです。
In MySQL 5.1.15
とそれ以降のバージョンでは、MERGE
テーブルの一部であるテーブルが開かれる時に次のチェックが行われます。もし一つでも適合性チェックに失敗したら、そのテーブルを開く事はできません。それぞれのテーブルに適応される適合性チェックは次のような物です。
MERGE
テーブルとまったく同じカラム数がなければいけません。
MERGE
テーブルのカラムの順番は、基礎となるテーブルのカラムの順番と一致しなければいけません。
さらに、親 MERGE
テーブルと、基礎となるテーブルのカラム仕様がそれぞれ比較されます。それぞれのカラムに対して、
MySQL は次のような事を確認します。
基礎となるテーブルのカラムタイプは、MERGE
テーブルのカラムタイプと等しい。
基礎となるテーブルのカラムの長さは、MERGE
テーブルのカラムの長さと等しい。
基礎となるテーブルのカラムとMERGE
テーブルのカラムはNULL
となり得る。
基礎となるテーブルは、少なくてもマージテーブルと同量のキーを持つ必要がある。基礎となるテーブルは、MERGE
よりも多量のキーを持つ事はできますが、その反対はできません。
それぞれのキーに対して
基礎となるテーブルのキータイプがマージテーブルのキータイプと等しいかどうかチェックして下さい。
基礎となるテーブルのキー定義中のキーパーツ(例 合成キー内の複数カラム)数が、マージテーブルのキー定義中のキーパーツ数を等しいかどうかチェックして下さい。
それぞれのキーパーツに対して
キーパーツの長さが等しいかどうか確認してください。
キーパーツタイプが等しいかどうか確認してください。
キーパーツの言語が等しいかどうか確認してください。
キーパーツが
NULL
になり得るかどうか確認してください。
MERGE
テーブルを作成した後、テーブルグループに対してまとめて機能するクエリを発行する事ができます。
mysql> SELECT * FROM total;
+---+---------+
| a | message |
+---+---------+
| 1 | Testing |
| 2 | table |
| 3 | t1 |
| 1 | Testing |
| 2 | table |
| 3 | t2 |
+---+---------+
MERGE
テーブルを再度別のMyISAM
テーブルのグループに対してマップするには、次の方法の一つを利用する事ができます。
MERGE
テーブルをDROP
して、もう一度作成してください。
基礎となるテーブルのリストを変更する為にALTER
TABLE
を利用して下さい。
tbl_name
UNION=(...)
MERGE
テーブルは、次のような問題を解決するのに役立ちます。
ログテーブル一式を簡単に処理する事ができます。例えば、違う月のデータを別々のテーブルに入力し、myisampackを利用してそれらを圧縮し、そしてそれらを一つの物として利用する為にMERGE
テーブルを作成する事ができます。
スピードを上げる事ができます。大きいリードオンリーのテーブルを、いくつかの基準に基づいて分割し、個々のテーブルを別々のディスク上に置く事ができます。このような場合は、MERGE
テーブルを利用した方が、大きいテーブルを利用するより早く処理ができます。
より有効な検索を行う事ができます。何を探しているかが明らかであれば、いくつかのクエリを分割されたテーブルのうちの一つだけで検索し、それ以外の物に対してはMERGE
テーブルを使用します。共通のテーブル一式を利用する、別々のMERGE
テーブルをいくつも持つ事もできます。
より有効な検索を行う事ができます。一つの大きなテーブルを修正するよりも、MERGE
テーブルに位置づけられた個々のテーブルを修正するほうが簡単です。
瞬時にいくつものテーブルを一つの物として位置づけます。MERGE
テーブルは個々のテーブルのインデックスを利用するので、それ自体のインデックスを整備する必要がありません。その結果、MERGE
テーブルの集まりは、作成や最位置づけを大変
速いスピードで行うことができます。(インデックスが何も作成されていないとしても、MERGE
テーブルを作成する時はインデックス定義を指定しなければいけない事を覚えておいてください。)
要求に応じて作成した大きなテーブルにテーブル一式がある場合、それらの代わりに要求に応じたMERGE
テーブルを作成する必要があります。この方が、ディスクの場所を節約し、すばやく処理する事ができます。
オペレーティングシステムのファイルサイズ制限を上回ります。一つ一つの
MyISAM
テーブルはこの制限に制約されますが、MyISAM
テーブルの集まりは制約されません。
その一つのテーブルに位置づけるMERGE
テーブルを定義する事によって、MyISAM
テーブルに仮名や同義語を作成する事ができます。この作業を行う事によって特に顕著なインパクトは現れません。(個々の読み取りに対していくつかの間接的なコールやmemcpy()
コールがあるだけです。)
MERGE
テーブルの不都合な点は次のような物です。
MERGE
テーブルに対して、同一のMyISAM
テーブルしか利用する事ができません。
MERGE
テーブルの中で、いくつものMyISAM
フィーチャーを利用する事はできません。例えば、MERGE
テーブル上でFULLTEXT
インデックスを作成する事はできません。(もちろん、基礎となるMyISAM
テーブル上に FULLTEXT
インデックスを作成する事はできますが、全文検索で
MERGE
テーブルを検索する事はできません。
もし MERGE
テーブルがテンポラリーでない場合、基礎となる全ての
MyISAM
テーブルもそうでなければいけません。もし
MERGE
テーブルがテンポラリーであれば、
MyISAM
テーブルはテンポラリー、テンポラリーでない物の両方が混在した物になり得ます。
MERGE
テーブルはより多くのファイルディスクリプタを利用します。もし、10個のクライアントが10個のテーブルに位置づけるMERGE
テーブルを利用する場合、サーバーは
(10 × 10) + 10
個のファイルディスクリプタを利用します。(10個のクライアントに対して10個のデータファイルディスクリプター、そして、10個のインデックスファイルディスクリプターがクライアントの間で共有されます。)
キーの読み込みが遅いです。
キーを読み込む時、 MERGE
ストレージエンジンは、与えられたキーにどれが一番近いかを確認するために、全ての基礎となるテーブルに対して読み込みを行う必要があります。次のキーを読み込む時、
それを見つける為にMERGE
ストレージエンジンは、読み込みバッファを検索する必要があります。
一つのキーバッファを使い切った時に限り、ストレージエンジンは次のキーブロックを読み込む必要があります。この為に
eq_ref
検索のMERGE
キーが遅くなりますが、ref
検索ほど遅くはありません。eq_ref
と
ref
の詳細については項6.2.1. 「EXPLAIN
を使用して、クエリを最適化する」をご参照ください。
追加情報
MERGE
ストレージエンジンを専門に扱うフォーラムがあります。http://forums.mysql.com/list.php?93。