このセクションでは、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
文字セットを使用する新しいオブジェクトが作成されます。