MySQL 8.0 リファレンスマニュアル


16.7.2 MERGE テーブルの問題点

MERGE テーブルの既知の問題点は次のとおりです。

  • 5.1.23 バージョンより前の MySQL Server では、MyISAM の非一時的な子供のテーブルを持つ一時的なマージテーブルを作成できました。

    バージョン 5.1.23 からは、MERGE の子供は親のテーブルを介してロックされました。 親が一時的であった場合、親がロックされなかったため、子供もロックされませんでした。 MyISAM テーブルを同時に使用すると、テーブルが破損しました。

  • ALTER TABLE を使用して MERGE テーブルを別のストレージエンジンに変えると、基礎テーブルへのマッピングが失われます。 その代わり、変更されたテーブルに基礎 MyISAM テーブルの行がコピーされ、そのときに、指定されたストレージエンジンを使用します。

  • MERGE テーブルの INSERT_METHOD テーブルオプションは、MERGE テーブルへの挿入にどの基礎 MyISAM テーブルを使用するかを示します。 ただし、その MyISAM テーブルに AUTO_INCREMENT テーブルオプションを使用しても、1 つ以上の行が MyISAM テーブルに直接挿入されるまで、MERGE テーブルへの挿入は有効になりません。

  • MERGE テーブルは、テーブル全体に一意制約を保持できません。 INSERT を実行すると、データは最初または最後の MyISAM テーブル (INSERT_METHOD オプションで指定されます) に入ります。 MySQL は一意のキー値が MyISAM テーブル内で一意のままであることを保証しますが、コレクション内のすべての基礎テーブルには保証しません。

  • MERGE エンジンは基本テーブルセットに一意性を適用できないため、REPLACE は期待どおりに機能しません。 次の 2 つの重要な事実があります。

    • REPLACE は、書き込もうとする基礎テーブルでのみ一意キー違反を検出できます (INSERT_METHOD オプションで指定されます)。 これは MERGE テーブル自体の違反とは異なります。

    • REPLACE は、一意キー違反を検出すると、書込み先の基礎となるテーブル (つまり、INSERT_METHOD オプションで決定された最初または最後のテーブル) の対応する行のみを変更します。

    INSERT ... ON DUPLICATE KEY UPDATE についても同様な考慮が適用されます。

  • MERGE テーブルはパーティション化をサポートしていません。 つまり、MERGE テーブルも、MERGE テーブルの基礎 MyISAM テーブルもパーティション化できません。

  • 開いた MERGE テーブルにマッピングされたどのテーブルにも、ANALYZE TABLEREPAIR TABLEOPTIMIZE TABLEALTER TABLEDROP TABLEDELETE (WHERE 句なし)、または TRUNCATE TABLE を使用すべきではありません。 そうする場合、MERGE テーブルは引き続き元のテーブルを参照しているため、予期しない結果となる可能性があります。 この問題に対処するには、名前付きの操作を行う前に FLUSH TABLES ステートメントを発行することで、確実に MERGE テーブルが開いたままにならないようにします。

    予期しない結果には、MERGE テーブルに対する操作でテーブルの破損が報告される可能性があります。 基礎 MyISAM テーブルで名前付き操作のあとにこれが発生した場合、破損メッセージは偽りです。 これに対処するには、MyISAM テーブルを変更したあとで FLUSH TABLES ステートメントを発行します。

  • MERGE ストレージエンジンのテーブルマッピングは MySQL の上位レイヤーから隠れているので、MERGE テーブルによって使用されているテーブルでの DROP TABLE は Windows では機能しません。 Windows では開いているファイルの削除を許可しないため、最初にすべての MERGE テーブルをフラッシュするか (FLUSH TABLES を使用します)、テーブルを削除する前に MERGE テーブルを削除する必要があります。

  • MyISAM テーブルと MERGE テーブルの定義は、テーブルにアクセスするときにチェックされます (たとえば、SELECT または INSERT ステートメントの一部として)。 このチェックは、テーブルの定義と親の MERGE テーブルの定義が、カラムの順番、タイプ、サイズ、および関連するインデックスを比較することで一致することを保証します。 テーブル間で違いがある場合、エラーが戻され、ステートメントは失敗します。 これらのチェックはテーブルが開かれたときに行われるため、カラムの変更、カラムの順序付け、エンジンの変更など、単一のテーブルの定義を変更すると、ステートメントが失敗します。

  • MERGE テーブルと、その基礎テーブルのインデックスの順番は同一でなければいけません。 ALTER TABLE を使用して、MERGE テーブル内で使用されるテーブルに UNIQUE インデックスを追加し、次に ALTER TABLE を使用して MERGE テーブル上に一意でないインデックスを追加した場合、基礎テーブル内に一意でないインデックスがすでに存在していると、それらのテーブルのインデックス順序は異なります。 (これが発生するのは、重複キーをすばやく検出できるように ALTER TABLE が一意でないインデックスの前に UNIQUE インデックスを配置するためです。) その結果、このようなインデックスを持つテーブルに対するクエリーは予想外の結果をもたらす可能性があります。

  • ERROR 1017 (HY000): Can't find file: 'tbl_name.MRG' (errno: 2)エラーメッセージが表示された場合、一般的に、いくつかの基礎テーブルが MyISAM ストレージエンジンを使用していないことを表しています。 これらのテーブルがすべて MyISAM であることを確認してください。

  • MERGE テーブルの行の最大値は 264 です (~1.844E+19 で、MyISAM テーブルの場合と同じ)。 複数の MyISAM テーブルを、この数よりも多くの行を含む単一の MERGE テーブルにマージできません。

  • 親の MERGE テーブルを持つ、異なる行フォーマットの基礎 MyISAM テーブルを使用すると、現在失敗することが知られています。 バグ #32364 を参照してください。

  • LOCK TABLES が実施されているときは、非一時的な MERGE テーブルの結合リストを変更できません。 次は動作しません

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

    ただし、一時的な MERGE テーブルではこれを行うことができます。

  • 一時的な MERGE としても、非一時的な MERGE テーブルとしても、CREATE ... SELECTMERGE テーブルを作成できません。 例:

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

    これを試みると、tbl_nameBASE TABLE ではないというエラーとなります。

  • あるケースでは、MERGE と基礎テーブル間で PACK_KEYS テーブルオプション値が異なると、基礎テーブルに CHAR または BINARY カラムが含まれている場合、予期しない結果になります。 回避策として、ALTER TABLE を使用して、関係するすべてのテーブルの PACK_KEYS 値が同じであることを保証します。 (Bug #50646)


関連キーワード:  テーブル, MERGE, エンジン, ストレージ, TABLE, 基礎, インデックス, FEDERATED, 変更, INSERT