utf16
文字セットは、補助文字のエンコーディングを可能にする拡張機能を備えた ucs2
文字セットです。
BMP 文字の場合、
utf16
とucs2
には、同じコード値、同じエンコーディング、同じ長さという同一のストレージ特性があります。補助文字の場合、
utf16
には、32 ビットを使用する文字を表すための特殊シーケンスがあります。 これは、「サロゲート」メカニズムと呼ばれます。0xffff
より大きな数値の場合、10 ビットを確保して、これらを0xd800
に追加し、最初の 16 ビット語に配置します。さらに 10 ビットを確保して、これらを0xdc00
に追加し、次の 16 ビット語に配置します。 この結果、すべての補助文字に 32 ビットが必要になります。このうち最初の 16 ビットは0xd800
と0xdbff
の間の数値であり、残りの 16 ビットは0xdc00
と0xdfff
の間の数値になります。 Unicode 4.0 ドキュメントの「15.5 Surrogates Area」に例が記載されています。
utf16
はサロゲートをサポートし、ucs2
をサポートしていないので、utf16
でのみ適用される妥当性チェックがあります。下位サロゲートがなければ上位サロゲートを挿入できず、逆も同様です。 例:
INSERT INTO t (ucs2_column) VALUES (0xd800); /* legal */
INSERT INTO t (utf16_column)VALUES (0xd800); /* illegal */
技術的に有効であるが真の Unicode ではない文字 (つまり、Unicode が「未割り当てコードポイント」または「個人使用」文字、さらには 0xffff
のように「不正」と見なす文字) に対する妥当性チェックはありません。 たとえば、U+F8FF
は Apple のロゴなので、これは有効です。
INSERT INTO t (utf16_column)VALUES (0xf8ff); /* legal */
このような文字は、すべてのユーザーに対し同じ意味を持たせることは期待できません。
MySQL は、最悪の場合 (文字が 4 バイトを必要とする場合) に対応する必要があるので、utf16
カラムまたはインデックスの最大長は、ucs2
カラムまたはインデックスの最大長の半分しかありません。 たとえば、MEMORY
テーブルのインデックスキーの最大長は 3072 バイトであるため、次のステートメントは、ucs2
および utf16
カラムに対して許可されている最長のインデックスを持つテーブルを作成します:
CREATE TABLE tf (s1 VARCHAR(1536) CHARACTER SET ucs2) ENGINE=MEMORY;
CREATE INDEX i ON tf (s1);
CREATE TABLE tg (s1 VARCHAR(768) CHARACTER SET utf16) ENGINE=MEMORY;
CREATE INDEX i ON tg (s1);