このページは機械翻訳したものです。
このセクションでは、utf8mb3 と utf8mb4 の文字セット間で文字データを変換する際に発生する可能性のある問題について説明します。
この説明では、主に utf8mb3 と utf8mb4 の間の変換に焦点を当てていますが、ucs2 文字セットと utf16 や utf32 などの文字セットの間の変換にも同様の原則が適用されます。
utf8mb3 と utf8mb4 の文字セットは、次の点で異なります:
utf8mb3では、Basic Multilingual Plane (BMP) の文字のみがサポートされます。utf8mb4では、BMP の外部にある補助文字もサポートされます。utf8mb3では、文字当たり最大 3 バイトが使用されます。utf8mb4では、文字当たり最大 4 バイトが使用されます。
この説明では、3 バイトおよび 4 バイトの UTF-8 文字セットデータの参照に関する明示的な utf8mb3 および utf8mb4 文字セット名について説明します。 ただし、テーブル定義では、utf8 が使用されるのは、このような定義で指定された utf8mb3 のインスタンスが、utf8mb3 のエイリアスである utf8 に MySQL によって変換されるためです。
utf8mb3 から utf8mb4 に変換する利点の 1 つは、アプリケーションで補助文字を使用できることです。 1 つのトレードオフは、これによってデータストレージ領域要件が増加する可能性があることです。
テーブルの内容に関しては、utf8mb3 から utf8mb4 への変換で問題は発生しません:
BMP 文字の場合、
utf8mb4とutf8mb3のストレージ特性は同じです: 同じコード値、同じエンコーディング、同じ長さ。補助文字の場合、
utf8mb4ではそれを格納するために 4 バイトが必要ですが、utf8mb3では文字を格納できません。utf8mb3カラムをutf8mb4に変換する場合、補助文字がないため、変換の心配は必要ありません。
テーブル構造に関して、主な潜在的な非互換性は次のとおりです:
可変長文字データ型 (
VARCHARおよびTEXT型) の場合、utf8mb4カラムに許可される最大長はutf8mb3カラムより少なくなります。すべての文字データ型 (
CHAR、VARCHARおよびTEXT型) について、utf8mb4カラムでインデックス付けできる最大文字数はutf8mb3カラムより少なくなります。
したがって、テーブルを utf8mb3 から utf8mb4 に変換するには、一部のカラムまたはインデックスの定義の変更が必要になる場合があります。
テーブルは、ALTER TABLE を使用して utf8mb3 から utf8mb4 に変換できます。 テーブルに次の定義があるとします:
CREATE TABLE t1 (
col1 CHAR(10) CHARACTER SET utf8 COLLATE utf8_unicode_ci NOT NULL,
col2 CHAR(10) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL
) CHARACTER SET utf8;
次のステートメントは、utf8mb4 を使用するように t1 を変換します。
ALTER TABLE t1
DEFAULT CHARACTER SET utf8mb4,
MODIFY col1 CHAR(10)
CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL,
MODIFY col2 CHAR(10)
CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NOT NULL;
utf8mb3 から utf8mb4 への変換時のキャッチは、bytes に関してカラムまたはインデックスキーの最大長が変更されないことです。 そのため、文字の最大長が 3 ではなく 4 なので、文字の点ではこれはより小さくなります。 CHAR、VARCHAR および TEXT データ型の場合は、MySQL テーブルを変換する際に次の問題を確認してください:
utf8mb3カラムのすべての定義をチェックし、ストレージエンジンの最大長を超えていないことを確認します。utf8mb3カラムのすべてのインデックスをチェックし、ストレージエンジンの最大長を超えていないことを確認します。 最大値は、ストレージエンジンの機能強化によって変更されることがあります。
前述の条件が適用される場合は、定義されているカラムまたはインデックスの長さを減らすか、utf8mb4 ではなく utf8mb3 を引き続き使用する必要があります。
次に、構造的な変更が必要な例をいくつか示します。
-
TINYTEXTカラムは、最大 255 バイトを保持できるので、3 バイトの文字は 85 個まで、4 バイトの文字は 63 個まで保持できます。utf8mb3を使用するTINYTEXTカラムがあるが、63 文字を超えることができる必要があるとします。 データ型もTEXTなどのより長い型に変更しないかぎり、これをutf8mb4に変換できません。同様に、
utf8mb3からutf8mb4に変換する場合は、非常に長いVARCHARカラムを長いTEXT型のいずれかに変更する必要があります。 -
InnoDBでは、COMPACTまたはREDUNDANTの行形式を使用するテーブルのインデックスの最大長は 767 バイトであるため、utf8mb3またはutf8mb4のカラムでは、それぞれ 255 文字または 191 文字までインデックス付けできます。 191 文字を超えるインデックスを持つutf8mb3カラムが現在ある場合は、インデックス付けする文字数を減らす必要があります。COMPACTまたはREDUNDANTの行形式を使用するInnoDBテーブルでは、次のカラムおよびインデックスの定義が有効です:col1 VARCHAR(500) CHARACTER SET utf8, INDEX (col1(255))代わりに
utf8mb4を使用するには、インデックスをより小さくする必要があります。col1 VARCHAR(500) CHARACTER SET utf8mb4, INDEX (col1(191))注記COMPRESSEDまたはDYNAMICの行形式を使用するInnoDBテーブルの場合、767 バイト (最大 3072 バイト) を超える index key prefixes が許可されます。 これらの行フォーマットを使用して作成されたテーブルでは、utf8mb3カラムまたはutf8mb4カラムに対してそれぞれ最大 1024 文字または 768 文字をインデックス付けできます。 関連情報については、セクション15.22「InnoDB の制限」,およびDYNAMIC 行フォーマットを参照してください。
前述の変更のタイプは、非常に長いカラムまたはインデックスを持つ場合にのみ必要になる可能性が高くなります。 それ以外の場合は、前述の ALTER TABLE を使用して、問題なくテーブルを utf8mb3 から utf8mb4 に変換できます。
次の項目は、その他の潜在的な非互換性をまとめたものです:
SET NAMES 'utf8mb4'では、接続文字セットに対して 4 バイトの文字セットを使用する必要があります。 4 バイト文字がサーバーから送信されていないかぎり、問題は起こりません。 それ以外の場合は、文字ごとに最大 3 バイトの受信を要求するアプリケーションで問題が発生する可能性があります。 反対に、4 バイトの文字の送信を要求するアプリケーションは、その文字がサーバーで認識されることを確認する必要があります。-
レプリケーションでは、補助文字をサポートする文字セットをソースで使用する場合、すべてのレプリカもそれらを理解する必要があります。
また、ソースとレプリカでテーブルの定義が異なる場合、予期しない結果が発生する可能性があることにも注意してください。 たとえば、インデックスキーの最大長が異なると、ソースで
utf8mb3を使用し、レプリカでutf8mb4を使用するリスクがあります。
utf8mb4, utf16, utf16le または utf32 に変換し、utf8mb3 または ucs2 に変換しなおすことにした場合 (古いバージョンの MySQL にダウングレードする場合など)、次の考慮事項が適用されます:
utf8mb3およびucs2データに問題はありません。サーバーは、変換元の文字セットを参照する定義を認識するのに十分な最新の状態である必要があります。
utf8mb4文字セットを参照するオブジェクト定義の場合、ダウングレード前に mysqldump でダンプし、ダンプファイルを編集してutf8mb4のインスタンスをutf8に変更し、データに 4 バイト文字がないかぎり、古いサーバーでファイルをリロードできます。 古いサーバーでは、ダンプファイルのオブジェクト定義にutf8が表示され、(3 バイト)utf8文字セットを使用する新しいオブジェクトが作成されます。