このセクションでは、Unicode 文字セットで使用可能な照合順序とその区別プロパティについて説明します。 Unicode の一般情報については、セクション10.9「Unicode のサポート」 を参照してください。
MySQL では、複数の Unicode 文字セットがサポートされています:
utf8mb4
: Unicode 文字セットの UTF-8 エンコーディング。文字ごとに 1 バイトから 4 バイトを使用します。utf8mb3
: Unicode 文字セットの UTF-8 エンコーディング。文字ごとに 1 バイトから 3 バイトを使用します。utf8
:utf8mb3
のエイリアス。ucs2
: 文字ごとに 2 バイトを使用した Unicode 文字セットの UCS-2 エンコーディング。utf16
: 文字ごとに 2 バイトまたは 4 バイトを使用する Unicode 文字セットの UTF-16 エンコーディング。ucs2
と似ていますが、補助文字の拡張子が付いています。utf16le
: Unicode 文字セットの UTF-16LE エンコーディング。utf16
と似ていますが、ビッグエンディアンではなくリトルエンディアンです。utf32
: 文字ごとに 4 バイトを使用する Unicode 文字セットの UTF-32 エンコーディング。
utf8mb3
文字セットは非推奨であり、将来の MySQL リリースで削除される予定です。 かわりに utf8mb4
を使用してください。 utf8
は現在 utf8mb3
のエイリアスですが、ある時点では utf8
が utf8mb4
への参照になることが予想されます。 utf8
の意味があいまいにならないように、utf8
ではなく文字セット参照に utf8mb4
を明示的に指定することを検討してください。
utf8mb4
, utf16
, utf16le
および utf32
は、BMP の外部にある Basic Multilingual Plane (BMP) 文字および補助文字をサポートしています。utf8
および ucs2
では BMP 文字のみがサポートされます。
ほとんどの Unicode 文字セットには、一般的な照合順序 (名前または言語指定子がない場合は_general
で示されます)、バイナリ照合順序 (名前に_bin
で示されます) および複数の言語固有の照合順序 (言語指定子で示されます) があります。 たとえば、utf8mb4
の場合、utf8mb4_general_ci
および utf8mb4_bin
はその一般照合およびバイナリ照合であり、utf8mb4_danish_ci
は言語固有の照合のいずれかです。
ほとんどの文字セットには単一のバイナリ照合順序があります。utf8mb4
は、次の例外です: utf8mb4_bin
および (MySQL 8.0.17 以降の)utf8mb4_0900_bin
。 これら 2 つのバイナリ照合順序は同じですが、パッド属性と照合順序特性によって区別されます。 照合パッド属性および文字照合ウェイトを参照してください。
utf16le
の照合サポートは制限されています。 使用可能な唯一の照合順序は、utf16le_general_ci
と utf16le_bin
です。 これらは、utf16_general_ci
と utf16_bin
に似ています。
MySQL は、http://www.unicode.org/reports/tr10/ で説明している Unicode 照合順序アルゴリズム (UCA) に従って
照合順序を実装します。 照合順序は、バージョン 4.0.0 UCA 重みキー (http://www.unicode.org/Public/UCA/4.0.0/allkeys-4.0.0.txt) を使用します。 xxx
_unicode_ci
照合では、Unicode 照合アルゴリズムの一部のみがサポートされます。 一部の文字はサポートされておらず、結合マークは完全にサポートされていません。 これは主に、ベトナム語、ヨルバ語、ナバホ語などの一部のより小さな言語に影響します。 結合された文字は、文字列比較で単一の Unicode 文字を使用して書き込まれた同じ文字とは異なるとみなされ、その 2 つの文字の長さは異なるとみなされます (たとえば、xxx
_unicode_ciCHAR_LENGTH()
関数または結果セットメタデータによって返されます)。
4.0.0 より上位の UCA バージョンに基づく Unicode 照合では、照合名にバージョンが含まれます。 例:
utf8mb4_unicode_520_ci
は UCA 5.2.0 重みキー (http://www.unicode.org/Public/UCA/5.2.0/allkeys.txt) に基づいています。utf8mb4_0900_ai_ci
は UCA 9.0.0 の重みキー (http://www.unicode.org/Public/UCA/9.0.0/allkeys.txt) に基づいています。
LOWER()
および UPPER()
関数は、引数の照合順序に従って大/小文字の折りたたみを実行します。 4.0.0 より大きい Unicode バージョンでのみ大文字と小文字のバージョンを持つ文字は、引数照合で十分な UCA バージョンが使用されている場合にのみ、これらの関数によって変換されます。
UCA 9.0.0 以上に基づく照合は、9.0.0 より前の UCA バージョンに基づく照合より高速です。 また、9.0.0 より前の UCA バージョンに基づく照合で使用される PAD SPACE
とは対照的に、NO PAD
のパッド属性もあります。 非バイナリ文字列を比較するために、NO PAD
照合順序では、文字列の末尾のスペースは他の文字と同様に扱われます (比較での後続領域の処理 を参照)。
照合のパッド属性を決定するには、PAD_ATTRIBUTE
カラムを含む INFORMATION_SCHEMA
COLLATIONS
テーブルを使用します。 例:
mysql> SELECT COLLATION_NAME, PAD_ATTRIBUTE
FROM INFORMATION_SCHEMA.COLLATIONS
WHERE CHARACTER_SET_NAME = 'utf8mb4';
+----------------------------+---------------+
| COLLATION_NAME | PAD_ATTRIBUTE |
+----------------------------+---------------+
| utf8mb4_general_ci | PAD SPACE |
| utf8mb4_bin | PAD SPACE |
| utf8mb4_unicode_ci | PAD SPACE |
| utf8mb4_icelandic_ci | PAD SPACE |
...
| utf8mb4_0900_ai_ci | NO PAD |
| utf8mb4_de_pb_0900_ai_ci | NO PAD |
| utf8mb4_is_0900_ai_ci | NO PAD |
...
| utf8mb4_ja_0900_as_cs | NO PAD |
| utf8mb4_ja_0900_as_cs_ks | NO PAD |
| utf8mb4_0900_as_ci | NO PAD |
| utf8mb4_ru_0900_ai_ci | NO PAD |
| utf8mb4_ru_0900_as_cs | NO PAD |
| utf8mb4_zh_0900_as_cs | NO PAD |
| utf8mb4_0900_bin | NO PAD |
+----------------------------+---------------+
NO PAD
照合順序を持つ非バイナリ文字列値 (CHAR
、VARCHAR
および TEXT
) の比較は、末尾の空白に関して他の照合順序とは異なります。 たとえば、'a'
と'a '
は、同じ文字列ではなく異なる文字列として比較されます。 これは、utf8mb4
のバイナリ照合を使用して確認できます。 utf8mb4_bin
の pad 属性は PAD SPACE
ですが、utf8mb4_0900_bin
の場合は NO PAD
です。 したがって、utf8mb4_0900_bin
に関連する操作では末尾にスペースが追加されず、末尾にスペースがある文字列を含む比較は、次の 2 つの照合順序で異なる場合があります:
mysql> CREATE TABLE t1 (c CHAR(10) COLLATE utf8mb4_bin);
Query OK, 0 rows affected (0.03 sec)
mysql> INSERT INTO t1 VALUES('a');
Query OK, 1 row affected (0.01 sec)
mysql> SELECT * FROM t1 WHERE c = 'a ';
+------+
| c |
+------+
| a |
+------+
1 row in set (0.00 sec)
mysql> ALTER TABLE t1 MODIFY c CHAR(10) COLLATE utf8mb4_0900_bin;
Query OK, 0 rows affected (0.02 sec)
Records: 0 Duplicates: 0 Warnings: 0
mysql> SELECT * FROM t1 WHERE c = 'a ';
Empty set (0.00 sec)
Unicode 照合アルゴリズム (UCA) のみに基づく順序付けが言語に対して適切に機能しない場合、MySQL は言語固有の Unicode 照合を実装します。 言語固有の照合は UCA ベースであり、追加の言語調整ルールがあります。 このようなルールの例は、このセクションの後半で説明します。 特定の言語の順序付けに関する質問については、unicode.org の http://www.unicode.org/cldr/charts/30/collation/index.html に Common Locale Data Repository (CLDR) 照合チャートが用意されています。
たとえば、非言語固有の utf8mb4_0900_ai_ci
および言語固有の utf8mb4_
Unicode 照合には、それぞれ次の特性があります:
LOCALE
_0900_ai_ci
照合は UCA 9.0.0 および CLDR v30 に基づいており、アクセントは区別されず、大/小文字も区別されません。 これらの特性は、照合名に
_0900
、_ai
および_ci
で示されます。 例外: CLDR で古典ラテンが定義されていないため、utf8mb4_la_0900_ai_ci
は CLDR に基づいていません。照合は、[U+0, U+10FFFF]の範囲のすべての文字に対して機能します。
照合順序が言語固有でない場合は、補助文字を含むすべての文字がデフォルトの順序 (後述) でソートされます。 照合順序が言語固有の場合、言語固有のルールに従って言語の文字が正しくソートされ、言語内にない文字がデフォルトの順序でソートされます。
デフォルトでは、照合では、DUCET テーブル (デフォルト Unicode 照合要素テーブル) にリストされているコードポイントを持つ文字が、テーブルに割り当てられている重み値に従ってソートされます。 照合では、UCA に従って構成される暗黙的な重み値を使用して、DUCET テーブルにコードポイントがリストされていない文字がソートされます。
言語固有でない照合の場合、縮約シーケンス内の文字は個別の文字として扱われます。 言語固有の照合順序の場合、縮約によって文字のソート順が変更されることがあります。
次のテーブルに示すロケールコードまたは言語名を含む照合名は、言語固有の照合です。 Unicode 文字セットには、これらの言語の照合順序を含めることができます。
表 10.3 Unicode 照合言語指定子
Language | 言語指定子 |
---|---|
中国語 | zh |
古典ラテン語 |
la または roman
|
クロアチア語 |
hr または croatian
|
チェコ語 |
cs または czech
|
デンマーク語 |
da または danish
|
エスペラント |
eo または esperanto
|
エストニア語 |
et または estonian
|
ドイツ電話帳の順序 |
de_pb または german2
|
ハンガリー語 |
hu または hungarian
|
アイスランド語 |
is または icelandic
|
日本語 | ja |
ラトビア語 |
lv または latvian
|
リトアニア語 |
lt または lithuanian
|
ペルシア語 | persian |
ポーランド語 |
pl または polish
|
ルーマニア語 |
ro または romanian
|
ロシア語 | ru |
シンハラ | sinhala |
スロバキア語 |
sk または slovak
|
スロベニア語 |
sl または slovenian
|
現代スペイン語 |
es または spanish
|
スペイン語 (繁体字) |
es_trad または spanish2
|
スウェーデン語 |
sv または swedish
|
トルコ語 |
tr または turkish
|
ベトナム語 |
vi または vietnamese
|
クロアチア語の照合順序は、これらのクロアチア語の文字に合わせて調整されます: Č
, Ć
, Dž
, Đ
, Lj
, Nj
, Š
, Ž
。
デンマーク語の照合順序は、ノルウェー語にも使用できます。
日本語の場合、utf8mb4
文字セットには utf8mb4_ja_0900_as_cs
照合順序および utf8mb4_ja_0900_as_cs_ks
照合順序が含まれます。 両方の照合でアクセントが区別され、大/小文字が区別されます。また、utf8mb4_ja_0900_as_cs_ks
はカタカナ文字をひらがな文字と区別し、utf8mb4_ja_0900_as_cs
はカタカナ文字とひらががな文字をソート用に同等として扱います。 日本語照合を必要とするが、kana 感度を必要としないアプリケーションでは、ソートパフォーマンスを向上させるために utf8mb4_ja_0900_as_cs
を使用できます。utf8mb4_ja_0900_as_cs
ではソートに 3 つの重みレベルが使用され、utf8mb4_ja_0900_as_cs_ks
では 4 つが使用されます。
アクセントを区別しない古典ラテン照合の場合、I
と J
は等しいと比較され、U
と V
は等しいと比較されます。 I
と J
、および U
と V
は、基本文字レベルと同じように比較されます。 つまり、J
はアクセント付き I
とみなされ、U
はアクセント付き V
とみなされます。
スペイン語照合は、最新のスペイン語および従来のスペイン語で使用できます。 どちらの場合も、ñ
(n-tilde) は n
と o
の間の個別の文字です。 また、スペイン語 (繁体字) の場合、ch
は c
と d
の間の個別の文字であり、ll
は l
と m
の間の個別の文字です。
スペイン語の従来の照合は、アストゥリア語およびガリシア語にも使用できます。
スウェーデン語照合にはスウェーデン語ルールが含まれます。 たとえば、スウェーデン語には、ドイツ語やフランス語を使用するユーザーでは予期しないような次の関係があります。
Ü = Y < Ö
Unicode 文字セットの場合、
照合順序を使用して実行する演算は、xxx
_general_ci
照合順序のものよりも高速です。 たとえば、xxx
_unicode_ciutf8_general_ci
照合順序の比較は、utf8_unicode_ci
の比較よりも高速ですが、精度は少し低くなります。 これは、utf8_unicode_ci
で拡張などのマッピングがサポートされているためです。つまり、一方の文字が他の文字の組合せと等しいと比較される場合です。 たとえば、ß
はドイツ語および他の一部の言語の ss
と同等です。utf8_unicode_ci
では、縮約および無視可能な文字もサポートされています。utf8_general_ci
は、拡張、縮小または無視可能な文字をサポートしないレガシー照合です。 文字間で 1 対 1 の比較しかできません。
さらに詳しく説明するために、utf8_general_ci
と utf8_unicode_ci
の両方で次の等価が保持されています (比較または検索での影響については、セクション10.8.6「照合順序の効果の例」 を参照してください):
Ä = A
Ö = O
Ü = U
照合順序間の違いは、次の式が utf8_general_ci
に当てはまるという点です。
ß = s
一方、次の式は、ドイツ語 DIN-1 順序 (辞書順序とも呼ばれます) をサポートする utf8_unicode_ci
に当てはまります。
ß = ss
utf8_unicode_ci
での順序付けが言語に対して適切に機能しない場合、MySQL は utf8
言語固有の照合を実装します。 たとえば、utf8_unicode_ci
は、ドイツ語辞書順序とフランス語には適切に機能するので、特殊な utf8
照合順序を作成する必要はありません。
utf8_general_ci
は、ß
が ss
ではなく s
と同等であることを除き、ドイツ語とフランス語の両方にも満足しています。 これがアプリケーションで許容可能な場合は、utf8_general_ci
のほうが高速なので、こちらを使用する必要があります。 これが許容できない場合 (たとえば、ドイツ語辞書順序が必要な場合) は、utf8_unicode_ci
のほうがより正確なので、こちらを使用してください。
ドイツ語 DIN-2 (電話帳) 順序が必要な場合は、utf8_german2_ci
照合順序を使用してください。これは次の文字セットを等しいものと見なします。
Ä = Æ = AE
Ö = Œ = OE
Ü = UE
ß = ss
utf8_german2_ci
は latin1_german2_ci
に似ていますが、後者は AE
と同等のÆ
または OE
と同等のŒ
を比較しません。 utf8_general_ci
で十分であるので、ドイツ語辞書順序のための latin1_german_ci
に対応する utf8_german_ci
はありません。
文字照合の重みは、次のように決定されます:
_bin
(バイナリ) 照合順序を除くすべての Unicode 照合順序について、MySQL はテーブル検索を実行して文字照合順序を検索します。utf8mb4_0900_bin
以外の_bin
照合順序の場合、重みはコードポイントに基づき、先行するゼロバイトが追加される場合があります。utf8mb4_0900_bin
の場合、重みはutf8mb4
エンコーディングバイトです。 ソート順序はutf8mb4_bin
の場合と同じですが、はるかに高速です。
照合加重は、WEIGHT_STRING()
関数を使用して表示できます。 (セクション12.8「文字列関数および演算子」を参照してください。) 照合順序で重み参照テーブルが使用されているが、文字がテーブルにない場合 (たとえば、「new」 文字であるため)、照合順序決定はより複雑になります:
一般照合 (
) の BMP 文字の場合、重みはコードポイントです。xxx
_general_ci-
UCA 照合順序 (たとえば、
と言語固有の照合順序) での BMP 文字の場合、次のアルゴリズムが適用されます。xxx
_unicode_ciif (code >= 0x3400 && code <= 0x4DB5) base= 0xFB80; /* CJK Ideograph Extension */ else if (code >= 0x4E00 && code <= 0x9FA5) base= 0xFB40; /* CJK Ideograph */ else base= 0xFBC0; /* All other characters */ aaaa= base + (code >> 15); bbbb= (code & 0x7FFF) | 0x8000;
結果は、
aaaa
にbbbb
が続いた 2 つの照合要素のシーケンスになります。 例:mysql> SELECT HEX(WEIGHT_STRING(_ucs2 0x04CF COLLATE ucs2_unicode_ci)); +----------------------------------------------------------+ | HEX(WEIGHT_STRING(_ucs2 0x04CF COLLATE ucs2_unicode_ci)) | +----------------------------------------------------------+ | FBC084CF | +----------------------------------------------------------+
したがって、
U+04cf CYRILLIC SMALL LETTER PALOCHKA
は、すべての UCA 4.0.0 照合順序で、U+04c0 CYRILLIC LETTER PALOCHKA
より大きくなります。 UCA 5.2.0 照合順序では、すべての palochka は一緒にソートされます。 -
一般的な照合順序の補助文字の場合、重みは
0xfffd REPLACEMENT CHARACTER
の重みです。 UCA 4.0.0 照合順序の補助文字の場合、照合重みは0xfffd
です。 つまり、MySQL では、すべての補助文字は互いに等しく、ほとんどすべての BMP 文字より大きくなります。デザレット文字と
COUNT(DISTINCT)
を使用した例:CREATE TABLE t (s1 VARCHAR(5) CHARACTER SET utf32 COLLATE utf32_unicode_ci); INSERT INTO t VALUES (0xfffd); /* REPLACEMENT CHARACTER */ INSERT INTO t VALUES (0x010412); /* DESERET CAPITAL LETTER BEE */ INSERT INTO t VALUES (0x010413); /* DESERET CAPITAL LETTER TEE */ SELECT COUNT(DISTINCT s1) FROM t;
結果は 2 です。これは、MySQL
照合順序で、置換文字はxxx
_unicode_ci0x0dc6
の重みを持ちますが、デザレット B とデザレット T はどちらも、0xfffd
の重みを持つからです。 (utf32_general_ci
照合順序がかわりに使用された場合、3 文字すべての照合順序の重みが0xfffd
であるため、結果は 1 になります。)くさび形文字と
WEIGHT_STRING()
を使用した例:/* The four characters in the INSERT string are 00000041 # LATIN CAPITAL LETTER A 0001218F # CUNEIFORM SIGN KAB 000121A7 # CUNEIFORM SIGN KISH 00000042 # LATIN CAPITAL LETTER B */ CREATE TABLE t (s1 CHAR(4) CHARACTER SET utf32 COLLATE utf32_unicode_ci); INSERT INTO t VALUES (0x000000410001218f000121a700000042); SELECT HEX(WEIGHT_STRING(s1)) FROM t;
結果は次のようになります。
0E33 FFFD FFFD 0E4A
0E33
と0E4A
は、UCA 4.0.0 の主要な重みです。FFFD
は KAB の重みであり、KISH の重みでもあります。すべての補助文字が互いに同じであるというルールは、最適ではありませんが、問題を引き起こすとは考えられません。 これらの文字は非常にまれであるため、複数文字列が完全に補助文字で構成されることは非常にまれです。 日本では、補助文字はあいまいな漢字表意文字であるので、一般的なユーザーは、いずれにしてもそれらの順序を気にしません。 実際には、行を MySQL ルールでソートし、次にコードポイント値でソートする場合は、次のように簡単です:
ORDER BY s1 COLLATE utf32_unicode_ci, s1 COLLATE utf32_bin
-
4.0.0 より上位の UCA バージョン (たとえば、
) に基づく補助文字の場合、補助文字の照合加重がすべて同じであるとはかぎりません。 一部には、UCAxxx
_unicode_520_ciallkeys.txt
ファイルからの明示的な重みがあります。 それ以外には、このアルゴリズムから計算された重みがあります。aaaa= base + (code >> 15); bbbb= (code & 0x7FFF) | 0x8000;
「文字のコード値による順序付け」と「文字のバイナリ表現による順序付け」と間には違いがあります。これは、サロゲートのために、utf16_bin
でのみ表示される違いです。
utf16_bin
(utf16
のバイナリ照合順序) が、「文字ごと」ではなく「バイトごと」のバイナリ比較であったとします。 その場合は、utf16_bin
での文字の順序は utf8_bin
での順序とは異なります。 たとえば、次の表には 2 つの珍しい文字が示されています。 最初の文字は E000
-FFFF
の範囲にあるので、サロゲートより大きくなりますが、補助文字より小さくなります。 2 番目の文字は補助文字です。
Code point Character utf8 utf16
---------- --------- ---- -----
0FF9D HALFWIDTH KATAKANA LETTER N EF BE 9D FF 9D
10384 UGARITIC LETTER DELTA F0 90 8E 84 D8 00 DF 84
表の 2 つの文字は、0xff9d
< 0x10384
であるので、コードポイント値による順序になります。 また、0xef
< 0xf0
なので、utf8
値による順序になります。 ただし、0xff
> 0xd8
なので、バイトごとの比較を使用する場合は、utf16
値による順序にはなりません。
したがって、MySQL の utf16_bin
照合順序は「バイトごと」にはなりません。 「コードポイントによる」順序になります。 MySQL は、utf16
での補助文字エンコーディングを認識すると、文字のコードポイント値に変換してから比較します。 したがって、utf8_bin
と utf16_bin
の順序付けは同じになります。 これは、UCS_BASIC 照合順序の SQL:2008 標準の要件に一致します。「UCS_BASIC は、ソートされている文字列の文字の Unicode スカラー値によって、順序付け全体が決定される照合順序です。 これは UCS 文字レパートリーに適用できます。 すべての文字レパートリーは、UCS レパートリーのサブセットなので、UCS_BASIC 照合順序は、すべての文字セットに適用できる可能性があります。 ノート 11: 文字の Unicode スカラー値は、符号なしの整数として扱われるそのコードポイントです。」
文字セットが ucs2
である場合、比較はバイトごとになりますが、いずれにしても、ucs2
文字列にはサロゲートを含めないでください。