このセクションでは、古い MySQL リリースから MySQL 5.6 にアップグレードするときに起きる可能性のある、Unicode サポートに関する問題について説明します。また、MySQL 5.6 から古いリリースにダウングレードするためのガイドラインも示します。
ほとんどの点で MySQL 5.6 にアップグレードしても、Unicode の使用法について問題が生じることはほとんどありませんが、非互換性の可能性のあるいくつかの領域があります。主な対象領域は次のとおりです。
可変長文字データ型 (
VARCHAR
型とTEXT
型) の場合、文字の最大長は、utf8mb4
カラムのほうがutf8
カラムよりも短くなります。すべての文字データ型 (
CHAR
型、VARCHAR
型、およびTEXT
型) で、インデックスを付けることができる文字の最大数は、utf8mb4
カラムのほうがutf8
カラムよりも少なくなります。
このため、utf8
から utf8mb4
にテーブルをアップグレードして補助文字サポートを利用する場合、一部のカラムまたはインデックス定義を変更する必要が生じることがあります。
テーブルは、ALTER TABLE
を使用することにより、utf8
から 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;
テーブルの内容については、utf8
から utf8mb4
への変換で問題は起こりません。
BMP 文字の場合、
utf8
とutf8mb4
のストレージ特性は同一で、コード値、エンコーディング、長さが同じです。補助文字については、
utf8
はこの文字をまったく格納できませんが、utf8mb4
は文字の格納に 4 バイトを必要とします。utf8
はこの文字をまったく格納しないので、utf8
カラムには補助文字がなく、utf8
データを古いバージョンの MySQL からアップグレードするときに、文字の変換やデータの損失について心配する必要はありません。
テーブル構造については、utf8
から utf8mb4
への変換時に、カラムまたはインデックスキーの最大長がバイトの点では変更されないという問題が生じます。そのため、文字の最大長が 3 ではなく 4 なので、文字の点ではこれはより小さくなります。CHAR
、VARCHAR
、および TEXT
データ型の場合、MySQL テーブルを変換するときに、次の点に注意してください。
utf8
カラムのすべての定義を調べて、それらがストレージエンジンの最大長を超えていないことを確認します。utf8
カラムのすべてのインデックスを調べて、それらがストレージエンジンの最大長を超えていないことを確認します。最大値は、ストレージエンジンの機能強化によって変更されることがあります。
前述の条件が当てはまる場合は、カラムまたはインデックスの定義された長さを減らすか、utf8mb4
ではなく utf8
を使用し続ける必要があります。
次に、構造的な変更が必要な例をいくつか示します。
-
TINYTEXT
カラムは、最大 255 バイトを保持できるので、3 バイトの文字は 85 個まで、4 バイトの文字は 63 個まで保持できます。utf8
を使用するTINYTEXT
カラムがあるが、63 個以上の文字を含められることが必要だとします。データ型もTEXT
などのより長い型に変更しないかぎり、これをutf8mb4
に変換できません。同様に非常に長い
VARCHAR
カラムは、utf8
からutf8mb4
に変換する場合は、より長いTEXT
型のいずれかに変更する必要があります。 -
InnoDB
には、COMPACT
またはREDUNDANT
行フォーマットを使用するテーブル用に 767 バイトの最大インデックス長があり、utf8
またはutf8mb4
カラムの場合、それぞれ最大 255 または 191 個の文字にインデックスを付けることができます。現在、インデックスが 191 個の文字より長いutf8
カラムがある場合、インデックスを付ける文字数を減らす必要があります。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
テーブルの場合、innodb_large_prefix
オプションを有効にすると、767 バイトより長いインデックスキープリフィクス (最大 3072 バイト) を許容できます。このようなテーブルの作成には、innodb_file_format=barracuda
およびinnodb_file_per_table=true
のオプション値も必要になります。)この場合、innodb_large_prefix
オプションを有効にすると、utf8
またはutf8mb4
カラムに対しそれぞれ最大 1024 または 768 個の文字にインデックスを付けることができます。関連情報については、セクション14.6.7「InnoDB テーブル上の制限」を参照してください。
前述の変更のタイプは、非常に長いカラムまたはインデックスを持つ場合にのみ必要になる可能性が高くなります。それ以外の場合は、utf8
から utf8mb4
に問題なくテーブルを変換できます。これを行うには、5.6 に適切にアップグレードしたあとで、このセクションですでに述べたように ALTER TABLE
を使用します。
次の項目は、非互換性の可能性のあるほかの領域についてまとめたものです。
4 バイトの UTF-8 (
utf8mb4
) のパフォーマンスは、3 バイトの UTF-8 (utf8
) のパフォーマンスより低下します。このペナルティーを望まない場合は、utf8
を引き続き使用してください。SET NAMES 'utf8mb4'
では、接続文字セットに対して 4 バイトの文字セットを使用する必要があります。4 バイト文字がサーバーから送信されていないかぎり、問題は起こりません。それ以外の場合は、文字ごとに最大 3 バイトの受信を要求するアプリケーションで問題が発生する可能性があります。反対に、4 バイトの文字の送信を要求するアプリケーションは、その文字がサーバーで認識されることを確認する必要があります。アプリケーションは、
utf16
、utf16le
、またはutf32
文字データを認識しない古いサーバーにこれらのデータを送信できません。-
レプリケーションでは、補助文字をサポートする文字セットがマスターで使用される場合、すべてのスレーブでもこれらの文字を認識する必要があります。MySQL 5.6 マスターから古いスレーブに複製しようとしたときに、
utf8
データはスレーブでutf8
と認識され、正しく複製されます。ただし、utf8mb4
、utf16
、utf16le
、またはutf32
データは送信できません。また、テーブルにマスターとスレーブについて異なる定義がある場合、予想外の結果を招くことがあるという一般的な原則に留意してください。たとえば、インデックスキー長の制限が異なると、マスターで
utf8
を使用し、スレーブでutf8mb4
を使用することは危険です。
MySQL 5.6 にアップグレードしてあり、古いリリースにダウングレードすることにした場合、次の考慮事項が該当します。
ucs2
およびutf8
データで問題が生じていない必要があります。utf8mb4
、utf16
、utf16le
、またはutf32
文字セットを参照するすべての定義は、古いサーバーで認識されません。utf8mb4
文字セットを参照するオブジェクト定義の場合、データ内に 4 バイト文字が存在しないかぎり、MySQL 5.6 で mysqldump を使用してこれらをダンプし、utf8mb4
のインスタンスをutf8
に変更するようにダンプファイルを編集し、このファイルを古いサーバーにリロードできます。古いサーバーは、ダンプファイルオブジェクト定義内のutf8
を認識し、(3 バイトの)utf8
文字セットを使用する新しいオブジェクトを作成します。