はじめに
MySQL 5.7 から 8.0 への変更点の1つとして、文字セット(charset)が latin1 から utf8mb4 になり、utf8mb4 の場合の照合順序(collation)が utf8mb4_0900_ai_ci になる、というのがあります。
この文字セットと照合順序について調べたことをメモしておきます。
確認環境
以下の環境で確認しています。 パラメーターグループはデフォルトのものを利用しています。
- Aurora MySQL 3.04.0
文字コード
そもそも文字コードが何かというのがはっきりわかってませんでした。 調べたところ、厳密には、符号化文字集合(CCS:Coded Caracter Set)と文字符号化方式(CES:Character Encoding Scheme)と呼ばれるものから成るもののようです。 文脈等によっては符号化文字集合だったり、文字符号化方式を表す場合もあるようです。
符号化文字集合は文字に番号を割り振ったもののようです。 JIS X 0208 や Unicode などが文字集合に当たるようです。
文字符号化方式は、Encoding Rule などとも呼ばれ、文字集合で定義した「群・面・区・点」の番号を、どのようなバイト列に変換するかのルールを決められたもののようです。 JIS X 0208 を符号化する方式としては、ISO-2022-JP(俗にいうJISコード)、Shift_JIS、EUC など、Unicode を符号化する方式としては、UTF-8, UTF-16 などになります。
MySQL の文字セットと照合順序
文字セットと照合順序とは何か、説明できるほど理解できていなかったので、まずはドキュメントを見てみたところ、下記のような記載がありました。
- MySQL :: MySQL 8.0 リファレンスマニュアル :: 10.1 一般の文字セットおよび照合順序
A character set is a set of symbols and encodings. A collation is a set of rules for comparing characters in a character set.
Suppose that we have an alphabet with four letters: A, B, a, b. We give each letter a number: A = 0, B = 1, a = 2, b = 3. The letter A is a symbol, the number 0 is the encoding for A, and the combination of all four letters and their encodings is a character set.
Suppose that we want to compare two string values, A and B. The simplest way to do this is to look at the encodings: 0 for A and 1 for B. Because 0 is less than 1, we say A is less than B. What we've just done is apply a collation to our character set. The collation is a set of rules (only one rule in this case): “compare the encodings.” We call this simplest of all possible collations a binary collation.
文字セットは、その文字とそれに対応するエンコード体系のセットであり、照合順序とは、文字セット内の文字を比較するためのルールを集めたものである、とあります。
MySQL 上での文字セットは、文字集合というよりは文字コードのニュアンスに違い感じかと思いました。ただドキュメント上文字コードという記述にはなっておらず、文字セットという表現のようでした。 なので、MySQL の文字セットとしての UTF-8 と、実際の文字コードの UTF-8 は厳密には別な意味を持つものになると思います。
例では、文字A, B, a, b に対して、エンコード体系として 0,1,2,3 の数字を割り当てる形になっており、"登場している文字すべて(ここでは4文字)とそれらへのエンコード体系の組合せ"が文字セットになる、ということのようです。 この例では A, B, a, b に、エンコード体系として 0,1,2,3 の数字の値が割当たる形になっているので、文字列値を比較する場合はエンコード体系の値を比較することで判別できます。エンコード体系での比較はバイナリ照合順序と呼ばれているようです。
ここでもし、小文字と大文字が同等である、とした場合、(1) 小文字の a および b を A および B と同等の文字として扱い、(2) エンコード体系を比較する、という2つの工程が必要になります。ほとんどの文字セットに多くの文字が存在するため、値を比較するための多くのルールがあります。
文字セット(charset)
使用可能な文字セットは以下のコマンドで出力できます。
mysql> show character set;
以下のような一覧が出力されました。
+----------+---------------------------------+---------------------+--------+ | Charset | Description | Default collation | Maxlen | +----------+---------------------------------+---------------------+--------+ | armscii8 | ARMSCII-8 Armenian | armscii8_general_ci | 1 | | ascii | US ASCII | ascii_general_ci | 1 | | big5 | Big5 Traditional Chinese | big5_chinese_ci | 2 | | binary | Binary pseudo charset | binary | 1 | | cp1250 | Windows Central European | cp1250_general_ci | 1 | | cp1251 | Windows Cyrillic | cp1251_general_ci | 1 | | cp1256 | Windows Arabic | cp1256_general_ci | 1 | | cp1257 | Windows Baltic | cp1257_general_ci | 1 | | cp850 | DOS West European | cp850_general_ci | 1 | | cp852 | DOS Central European | cp852_general_ci | 1 | | cp866 | DOS Russian | cp866_general_ci | 1 | | cp932 | SJIS for Windows Japanese | cp932_japanese_ci | 2 | | dec8 | DEC West European | dec8_swedish_ci | 1 | | eucjpms | UJIS for Windows Japanese | eucjpms_japanese_ci | 3 | | euckr | EUC-KR Korean | euckr_korean_ci | 2 | | gb18030 | China National Standard GB18030 | gb18030_chinese_ci | 4 | | gb2312 | GB2312 Simplified Chinese | gb2312_chinese_ci | 2 | | gbk | GBK Simplified Chinese | gbk_chinese_ci | 2 | | geostd8 | GEOSTD8 Georgian | geostd8_general_ci | 1 | | greek | ISO 8859-7 Greek | greek_general_ci | 1 | | hebrew | ISO 8859-8 Hebrew | hebrew_general_ci | 1 | | hp8 | HP West European | hp8_english_ci | 1 | | keybcs2 | DOS Kamenicky Czech-Slovak | keybcs2_general_ci | 1 | | koi8r | KOI8-R Relcom Russian | koi8r_general_ci | 1 | | koi8u | KOI8-U Ukrainian | koi8u_general_ci | 1 | | latin1 | cp1252 West European | latin1_swedish_ci | 1 | | latin2 | ISO 8859-2 Central European | latin2_general_ci | 1 | | latin5 | ISO 8859-9 Turkish | latin5_turkish_ci | 1 | | latin7 | ISO 8859-13 Baltic | latin7_general_ci | 1 | | macce | Mac Central European | macce_general_ci | 1 | | macroman | Mac West European | macroman_general_ci | 1 | | sjis | Shift-JIS Japanese | sjis_japanese_ci | 2 | | swe7 | 7bit Swedish | swe7_swedish_ci | 1 | | tis620 | TIS620 Thai | tis620_thai_ci | 1 | | ucs2 | UCS-2 Unicode | ucs2_general_ci | 2 | | ujis | EUC-JP Japanese | ujis_japanese_ci | 3 | | utf16 | UTF-16 Unicode | utf16_general_ci | 4 | | utf16le | UTF-16LE Unicode | utf16le_general_ci | 4 | | utf32 | UTF-32 Unicode | utf32_general_ci | 4 | | utf8 | UTF-8 Unicode | utf8_general_ci | 3 | | utf8mb4 | UTF-8 Unicode | utf8mb4_0900_ai_ci | 4 | +----------+---------------------------------+---------------------+--------+ 41 rows in set (0.00 sec)
utf8mb3
は utf8
のエイリアスとして存在している、という記述がドキュメントにはありますが、Aurora MySQL v3 では廃止されているようで、出力一覧にはありませんでした。
- https://docs.aws.amazon.com/AmazonRDS/latest/AuroraUserGuide/AuroraMySQL.Updates.MajorVersionUpgrade.html#AuroraMySQL.upgrade-prechecks
For improved Unicode support, consider converting objects that use the utf8mb3 charset to use the utf8mb4 charset. The utf8mb3 character set is deprecated. Also, consider using utf8mb4 for character set references instead of utf8, because currently utf8 is an alias for the utf8mb3 charset.
For more information, see The utf8mb3 character set (3-byte UTF-8 unicode encoding) in the MySQL documentation.
照合順序(collation)
照合順序は以下のコマンドで出力できます。
mysql> show collation;
以下のような一覧が出力されました。
照合順序についても、 utf8mb3
は出力一覧にはありませんでした。
+----------------------------+----------+-----+---------+----------+---------+---------------+ | Collation | Charset | Id | Default | Compiled | Sortlen | Pad_attribute | +----------------------------+----------+-----+---------+----------+---------+---------------+ | armscii8_bin | armscii8 | 64 | | Yes | 1 | PAD SPACE | | armscii8_general_ci | armscii8 | 32 | Yes | Yes | 1 | PAD SPACE | | ascii_bin | ascii | 65 | | Yes | 1 | PAD SPACE | | ascii_general_ci | ascii | 11 | Yes | Yes | 1 | PAD SPACE | | big5_bin | big5 | 84 | | Yes | 1 | PAD SPACE | | big5_chinese_ci | big5 | 1 | Yes | Yes | 1 | PAD SPACE | | binary | binary | 63 | Yes | Yes | 1 | NO PAD | | cp1250_bin | cp1250 | 66 | | Yes | 1 | PAD SPACE | | cp1250_croatian_ci | cp1250 | 44 | | Yes | 1 | PAD SPACE | | cp1250_czech_cs | cp1250 | 34 | | Yes | 2 | PAD SPACE | | cp1250_general_ci | cp1250 | 26 | Yes | Yes | 1 | PAD SPACE | | cp1250_polish_ci | cp1250 | 99 | | Yes | 1 | PAD SPACE | | cp1251_bin | cp1251 | 50 | | Yes | 1 | PAD SPACE | | cp1251_bulgarian_ci | cp1251 | 14 | | Yes | 1 | PAD SPACE | | cp1251_general_ci | cp1251 | 51 | Yes | Yes | 1 | PAD SPACE | | cp1251_general_cs | cp1251 | 52 | | Yes | 1 | PAD SPACE | | cp1251_ukrainian_ci | cp1251 | 23 | | Yes | 1 | PAD SPACE | | cp1256_bin | cp1256 | 67 | | Yes | 1 | PAD SPACE | | cp1256_general_ci | cp1256 | 57 | Yes | Yes | 1 | PAD SPACE | | cp1257_bin | cp1257 | 58 | | Yes | 1 | PAD SPACE | | cp1257_general_ci | cp1257 | 59 | Yes | Yes | 1 | PAD SPACE | | cp1257_lithuanian_ci | cp1257 | 29 | | Yes | 1 | PAD SPACE | | cp850_bin | cp850 | 80 | | Yes | 1 | PAD SPACE | | cp850_general_ci | cp850 | 4 | Yes | Yes | 1 | PAD SPACE | | cp852_bin | cp852 | 81 | | Yes | 1 | PAD SPACE | | cp852_general_ci | cp852 | 40 | Yes | Yes | 1 | PAD SPACE | | cp866_bin | cp866 | 68 | | Yes | 1 | PAD SPACE | | cp866_general_ci | cp866 | 36 | Yes | Yes | 1 | PAD SPACE | | cp932_bin | cp932 | 96 | | Yes | 1 | PAD SPACE | | cp932_japanese_ci | cp932 | 95 | Yes | Yes | 1 | PAD SPACE | | dec8_bin | dec8 | 69 | | Yes | 1 | PAD SPACE | | dec8_swedish_ci | dec8 | 3 | Yes | Yes | 1 | PAD SPACE | | eucjpms_bin | eucjpms | 98 | | Yes | 1 | PAD SPACE | | eucjpms_japanese_ci | eucjpms | 97 | Yes | Yes | 1 | PAD SPACE | | euckr_bin | euckr | 85 | | Yes | 1 | PAD SPACE | | euckr_korean_ci | euckr | 19 | Yes | Yes | 1 | PAD SPACE | | gb18030_bin | gb18030 | 249 | | Yes | 1 | PAD SPACE | | gb18030_chinese_ci | gb18030 | 248 | Yes | Yes | 2 | PAD SPACE | | gb18030_unicode_520_ci | gb18030 | 250 | | Yes | 8 | PAD SPACE | | gb2312_bin | gb2312 | 86 | | Yes | 1 | PAD SPACE | | gb2312_chinese_ci | gb2312 | 24 | Yes | Yes | 1 | PAD SPACE | | gbk_bin | gbk | 87 | | Yes | 1 | PAD SPACE | | gbk_chinese_ci | gbk | 28 | Yes | Yes | 1 | PAD SPACE | | geostd8_bin | geostd8 | 93 | | Yes | 1 | PAD SPACE | | geostd8_general_ci | geostd8 | 92 | Yes | Yes | 1 | PAD SPACE | | greek_bin | greek | 70 | | Yes | 1 | PAD SPACE | | greek_general_ci | greek | 25 | Yes | Yes | 1 | PAD SPACE | | hebrew_bin | hebrew | 71 | | Yes | 1 | PAD SPACE | | hebrew_general_ci | hebrew | 16 | Yes | Yes | 1 | PAD SPACE | | hp8_bin | hp8 | 72 | | Yes | 1 | PAD SPACE | | hp8_english_ci | hp8 | 6 | Yes | Yes | 1 | PAD SPACE | | keybcs2_bin | keybcs2 | 73 | | Yes | 1 | PAD SPACE | | keybcs2_general_ci | keybcs2 | 37 | Yes | Yes | 1 | PAD SPACE | | koi8r_bin | koi8r | 74 | | Yes | 1 | PAD SPACE | | koi8r_general_ci | koi8r | 7 | Yes | Yes | 1 | PAD SPACE | | koi8u_bin | koi8u | 75 | | Yes | 1 | PAD SPACE | | koi8u_general_ci | koi8u | 22 | Yes | Yes | 1 | PAD SPACE | | latin1_bin | latin1 | 47 | | Yes | 1 | PAD SPACE | | latin1_danish_ci | latin1 | 15 | | Yes | 1 | PAD SPACE | | latin1_general_ci | latin1 | 48 | | Yes | 1 | PAD SPACE | | latin1_general_cs | latin1 | 49 | | Yes | 1 | PAD SPACE | | latin1_german1_ci | latin1 | 5 | | Yes | 1 | PAD SPACE | | latin1_german2_ci | latin1 | 31 | | Yes | 2 | PAD SPACE | | latin1_spanish_ci | latin1 | 94 | | Yes | 1 | PAD SPACE | | latin1_swedish_ci | latin1 | 8 | Yes | Yes | 1 | PAD SPACE | | latin2_bin | latin2 | 77 | | Yes | 1 | PAD SPACE | | latin2_croatian_ci | latin2 | 27 | | Yes | 1 | PAD SPACE | | latin2_czech_cs | latin2 | 2 | | Yes | 4 | PAD SPACE | | latin2_general_ci | latin2 | 9 | Yes | Yes | 1 | PAD SPACE | | latin2_hungarian_ci | latin2 | 21 | | Yes | 1 | PAD SPACE | | latin5_bin | latin5 | 78 | | Yes | 1 | PAD SPACE | | latin5_turkish_ci | latin5 | 30 | Yes | Yes | 1 | PAD SPACE | | latin7_bin | latin7 | 79 | | Yes | 1 | PAD SPACE | | latin7_estonian_cs | latin7 | 20 | | Yes | 1 | PAD SPACE | | latin7_general_ci | latin7 | 41 | Yes | Yes | 1 | PAD SPACE | | latin7_general_cs | latin7 | 42 | | Yes | 1 | PAD SPACE | | macce_bin | macce | 43 | | Yes | 1 | PAD SPACE | | macce_general_ci | macce | 38 | Yes | Yes | 1 | PAD SPACE | | macroman_bin | macroman | 53 | | Yes | 1 | PAD SPACE | | macroman_general_ci | macroman | 39 | Yes | Yes | 1 | PAD SPACE | | sjis_bin | sjis | 88 | | Yes | 1 | PAD SPACE | | sjis_japanese_ci | sjis | 13 | Yes | Yes | 1 | PAD SPACE | | swe7_bin | swe7 | 82 | | Yes | 1 | PAD SPACE | | swe7_swedish_ci | swe7 | 10 | Yes | Yes | 1 | PAD SPACE | | tis620_bin | tis620 | 89 | | Yes | 1 | PAD SPACE | | tis620_thai_ci | tis620 | 18 | Yes | Yes | 4 | PAD SPACE | | ucs2_bin | ucs2 | 90 | | Yes | 1 | PAD SPACE | | ucs2_croatian_ci | ucs2 | 149 | | Yes | 8 | PAD SPACE | | ucs2_czech_ci | ucs2 | 138 | | Yes | 8 | PAD SPACE | | ucs2_danish_ci | ucs2 | 139 | | Yes | 8 | PAD SPACE | | ucs2_esperanto_ci | ucs2 | 145 | | Yes | 8 | PAD SPACE | | ucs2_estonian_ci | ucs2 | 134 | | Yes | 8 | PAD SPACE | | ucs2_general_ci | ucs2 | 35 | Yes | Yes | 1 | PAD SPACE | | ucs2_general_mysql500_ci | ucs2 | 159 | | Yes | 1 | PAD SPACE | | ucs2_german2_ci | ucs2 | 148 | | Yes | 8 | PAD SPACE | | ucs2_hungarian_ci | ucs2 | 146 | | Yes | 8 | PAD SPACE | | ucs2_icelandic_ci | ucs2 | 129 | | Yes | 8 | PAD SPACE | | ucs2_latvian_ci | ucs2 | 130 | | Yes | 8 | PAD SPACE | | ucs2_lithuanian_ci | ucs2 | 140 | | Yes | 8 | PAD SPACE | | ucs2_persian_ci | ucs2 | 144 | | Yes | 8 | PAD SPACE | | ucs2_polish_ci | ucs2 | 133 | | Yes | 8 | PAD SPACE | | ucs2_romanian_ci | ucs2 | 131 | | Yes | 8 | PAD SPACE | | ucs2_roman_ci | ucs2 | 143 | | Yes | 8 | PAD SPACE | | ucs2_sinhala_ci | ucs2 | 147 | | Yes | 8 | PAD SPACE | | ucs2_slovak_ci | ucs2 | 141 | | Yes | 8 | PAD SPACE | | ucs2_slovenian_ci | ucs2 | 132 | | Yes | 8 | PAD SPACE | | ucs2_spanish2_ci | ucs2 | 142 | | Yes | 8 | PAD SPACE | | ucs2_spanish_ci | ucs2 | 135 | | Yes | 8 | PAD SPACE | | ucs2_swedish_ci | ucs2 | 136 | | Yes | 8 | PAD SPACE | | ucs2_turkish_ci | ucs2 | 137 | | Yes | 8 | PAD SPACE | | ucs2_unicode_520_ci | ucs2 | 150 | | Yes | 8 | PAD SPACE | | ucs2_unicode_ci | ucs2 | 128 | | Yes | 8 | PAD SPACE | | ucs2_vietnamese_ci | ucs2 | 151 | | Yes | 8 | PAD SPACE | | ujis_bin | ujis | 91 | | Yes | 1 | PAD SPACE | | ujis_japanese_ci | ujis | 12 | Yes | Yes | 1 | PAD SPACE | | utf16le_bin | utf16le | 62 | | Yes | 1 | PAD SPACE | | utf16le_general_ci | utf16le | 56 | Yes | Yes | 1 | PAD SPACE | | utf16_bin | utf16 | 55 | | Yes | 1 | PAD SPACE | | utf16_croatian_ci | utf16 | 122 | | Yes | 8 | PAD SPACE | | utf16_czech_ci | utf16 | 111 | | Yes | 8 | PAD SPACE | | utf16_danish_ci | utf16 | 112 | | Yes | 8 | PAD SPACE | | utf16_esperanto_ci | utf16 | 118 | | Yes | 8 | PAD SPACE | | utf16_estonian_ci | utf16 | 107 | | Yes | 8 | PAD SPACE | | utf16_general_ci | utf16 | 54 | Yes | Yes | 1 | PAD SPACE | | utf16_german2_ci | utf16 | 121 | | Yes | 8 | PAD SPACE | | utf16_hungarian_ci | utf16 | 119 | | Yes | 8 | PAD SPACE | | utf16_icelandic_ci | utf16 | 102 | | Yes | 8 | PAD SPACE | | utf16_latvian_ci | utf16 | 103 | | Yes | 8 | PAD SPACE | | utf16_lithuanian_ci | utf16 | 113 | | Yes | 8 | PAD SPACE | | utf16_persian_ci | utf16 | 117 | | Yes | 8 | PAD SPACE | | utf16_polish_ci | utf16 | 106 | | Yes | 8 | PAD SPACE | | utf16_romanian_ci | utf16 | 104 | | Yes | 8 | PAD SPACE | | utf16_roman_ci | utf16 | 116 | | Yes | 8 | PAD SPACE | | utf16_sinhala_ci | utf16 | 120 | | Yes | 8 | PAD SPACE | | utf16_slovak_ci | utf16 | 114 | | Yes | 8 | PAD SPACE | | utf16_slovenian_ci | utf16 | 105 | | Yes | 8 | PAD SPACE | | utf16_spanish2_ci | utf16 | 115 | | Yes | 8 | PAD SPACE | | utf16_spanish_ci | utf16 | 108 | | Yes | 8 | PAD SPACE | | utf16_swedish_ci | utf16 | 109 | | Yes | 8 | PAD SPACE | | utf16_turkish_ci | utf16 | 110 | | Yes | 8 | PAD SPACE | | utf16_unicode_520_ci | utf16 | 123 | | Yes | 8 | PAD SPACE | | utf16_unicode_ci | utf16 | 101 | | Yes | 8 | PAD SPACE | | utf16_vietnamese_ci | utf16 | 124 | | Yes | 8 | PAD SPACE | | utf32_bin | utf32 | 61 | | Yes | 1 | PAD SPACE | | utf32_croatian_ci | utf32 | 181 | | Yes | 8 | PAD SPACE | | utf32_czech_ci | utf32 | 170 | | Yes | 8 | PAD SPACE | | utf32_danish_ci | utf32 | 171 | | Yes | 8 | PAD SPACE | | utf32_esperanto_ci | utf32 | 177 | | Yes | 8 | PAD SPACE | | utf32_estonian_ci | utf32 | 166 | | Yes | 8 | PAD SPACE | | utf32_general_ci | utf32 | 60 | Yes | Yes | 1 | PAD SPACE | | utf32_german2_ci | utf32 | 180 | | Yes | 8 | PAD SPACE | | utf32_hungarian_ci | utf32 | 178 | | Yes | 8 | PAD SPACE | | utf32_icelandic_ci | utf32 | 161 | | Yes | 8 | PAD SPACE | | utf32_latvian_ci | utf32 | 162 | | Yes | 8 | PAD SPACE | | utf32_lithuanian_ci | utf32 | 172 | | Yes | 8 | PAD SPACE | | utf32_persian_ci | utf32 | 176 | | Yes | 8 | PAD SPACE | | utf32_polish_ci | utf32 | 165 | | Yes | 8 | PAD SPACE | | utf32_romanian_ci | utf32 | 163 | | Yes | 8 | PAD SPACE | | utf32_roman_ci | utf32 | 175 | | Yes | 8 | PAD SPACE | | utf32_sinhala_ci | utf32 | 179 | | Yes | 8 | PAD SPACE | | utf32_slovak_ci | utf32 | 173 | | Yes | 8 | PAD SPACE | | utf32_slovenian_ci | utf32 | 164 | | Yes | 8 | PAD SPACE | | utf32_spanish2_ci | utf32 | 174 | | Yes | 8 | PAD SPACE | | utf32_spanish_ci | utf32 | 167 | | Yes | 8 | PAD SPACE | | utf32_swedish_ci | utf32 | 168 | | Yes | 8 | PAD SPACE | | utf32_turkish_ci | utf32 | 169 | | Yes | 8 | PAD SPACE | | utf32_unicode_520_ci | utf32 | 182 | | Yes | 8 | PAD SPACE | | utf32_unicode_ci | utf32 | 160 | | Yes | 8 | PAD SPACE | | utf32_vietnamese_ci | utf32 | 183 | | Yes | 8 | PAD SPACE | | utf8mb4_0900_ai_ci | utf8mb4 | 255 | Yes | Yes | 0 | NO PAD | | utf8mb4_0900_as_ci | utf8mb4 | 305 | | Yes | 0 | NO PAD | | utf8mb4_0900_as_cs | utf8mb4 | 278 | | Yes | 0 | NO PAD | | utf8mb4_0900_bin | utf8mb4 | 309 | | Yes | 1 | NO PAD | | utf8mb4_bin | utf8mb4 | 46 | | Yes | 1 | PAD SPACE | | utf8mb4_croatian_ci | utf8mb4 | 245 | | Yes | 8 | PAD SPACE | | utf8mb4_cs_0900_ai_ci | utf8mb4 | 266 | | Yes | 0 | NO PAD | | utf8mb4_cs_0900_as_cs | utf8mb4 | 289 | | Yes | 0 | NO PAD | | utf8mb4_czech_ci | utf8mb4 | 234 | | Yes | 8 | PAD SPACE | | utf8mb4_danish_ci | utf8mb4 | 235 | | Yes | 8 | PAD SPACE | | utf8mb4_da_0900_ai_ci | utf8mb4 | 267 | | Yes | 0 | NO PAD | | utf8mb4_da_0900_as_cs | utf8mb4 | 290 | | Yes | 0 | NO PAD | | utf8mb4_de_pb_0900_ai_ci | utf8mb4 | 256 | | Yes | 0 | NO PAD | | utf8mb4_de_pb_0900_as_cs | utf8mb4 | 279 | | Yes | 0 | NO PAD | | utf8mb4_eo_0900_ai_ci | utf8mb4 | 273 | | Yes | 0 | NO PAD | | utf8mb4_eo_0900_as_cs | utf8mb4 | 296 | | Yes | 0 | NO PAD | | utf8mb4_esperanto_ci | utf8mb4 | 241 | | Yes | 8 | PAD SPACE | | utf8mb4_estonian_ci | utf8mb4 | 230 | | Yes | 8 | PAD SPACE | | utf8mb4_es_0900_ai_ci | utf8mb4 | 263 | | Yes | 0 | NO PAD | | utf8mb4_es_0900_as_cs | utf8mb4 | 286 | | Yes | 0 | NO PAD | | utf8mb4_es_trad_0900_ai_ci | utf8mb4 | 270 | | Yes | 0 | NO PAD | | utf8mb4_es_trad_0900_as_cs | utf8mb4 | 293 | | Yes | 0 | NO PAD | | utf8mb4_et_0900_ai_ci | utf8mb4 | 262 | | Yes | 0 | NO PAD | | utf8mb4_et_0900_as_cs | utf8mb4 | 285 | | Yes | 0 | NO PAD | | utf8mb4_general_ci | utf8mb4 | 45 | | Yes | 1 | PAD SPACE | | utf8mb4_german2_ci | utf8mb4 | 244 | | Yes | 8 | PAD SPACE | | utf8mb4_hr_0900_ai_ci | utf8mb4 | 275 | | Yes | 0 | NO PAD | | utf8mb4_hr_0900_as_cs | utf8mb4 | 298 | | Yes | 0 | NO PAD | | utf8mb4_hungarian_ci | utf8mb4 | 242 | | Yes | 8 | PAD SPACE | | utf8mb4_hu_0900_ai_ci | utf8mb4 | 274 | | Yes | 0 | NO PAD | | utf8mb4_hu_0900_as_cs | utf8mb4 | 297 | | Yes | 0 | NO PAD | | utf8mb4_icelandic_ci | utf8mb4 | 225 | | Yes | 8 | PAD SPACE | | utf8mb4_is_0900_ai_ci | utf8mb4 | 257 | | Yes | 0 | NO PAD | | utf8mb4_is_0900_as_cs | utf8mb4 | 280 | | Yes | 0 | NO PAD | | utf8mb4_ja_0900_as_cs | utf8mb4 | 303 | | Yes | 0 | NO PAD | | utf8mb4_ja_0900_as_cs_ks | utf8mb4 | 304 | | Yes | 24 | NO PAD | | utf8mb4_latvian_ci | utf8mb4 | 226 | | Yes | 8 | PAD SPACE | | utf8mb4_la_0900_ai_ci | utf8mb4 | 271 | | Yes | 0 | NO PAD | | utf8mb4_la_0900_as_cs | utf8mb4 | 294 | | Yes | 0 | NO PAD | | utf8mb4_lithuanian_ci | utf8mb4 | 236 | | Yes | 8 | PAD SPACE | | utf8mb4_lt_0900_ai_ci | utf8mb4 | 268 | | Yes | 0 | NO PAD | | utf8mb4_lt_0900_as_cs | utf8mb4 | 291 | | Yes | 0 | NO PAD | | utf8mb4_lv_0900_ai_ci | utf8mb4 | 258 | | Yes | 0 | NO PAD | | utf8mb4_lv_0900_as_cs | utf8mb4 | 281 | | Yes | 0 | NO PAD | | utf8mb4_persian_ci | utf8mb4 | 240 | | Yes | 8 | PAD SPACE | | utf8mb4_pl_0900_ai_ci | utf8mb4 | 261 | | Yes | 0 | NO PAD | | utf8mb4_pl_0900_as_cs | utf8mb4 | 284 | | Yes | 0 | NO PAD | | utf8mb4_polish_ci | utf8mb4 | 229 | | Yes | 8 | PAD SPACE | | utf8mb4_romanian_ci | utf8mb4 | 227 | | Yes | 8 | PAD SPACE | | utf8mb4_roman_ci | utf8mb4 | 239 | | Yes | 8 | PAD SPACE | | utf8mb4_ro_0900_ai_ci | utf8mb4 | 259 | | Yes | 0 | NO PAD | | utf8mb4_ro_0900_as_cs | utf8mb4 | 282 | | Yes | 0 | NO PAD | | utf8mb4_ru_0900_ai_ci | utf8mb4 | 306 | | Yes | 0 | NO PAD | | utf8mb4_ru_0900_as_cs | utf8mb4 | 307 | | Yes | 0 | NO PAD | | utf8mb4_sinhala_ci | utf8mb4 | 243 | | Yes | 8 | PAD SPACE | | utf8mb4_sk_0900_ai_ci | utf8mb4 | 269 | | Yes | 0 | NO PAD | | utf8mb4_sk_0900_as_cs | utf8mb4 | 292 | | Yes | 0 | NO PAD | | utf8mb4_slovak_ci | utf8mb4 | 237 | | Yes | 8 | PAD SPACE | | utf8mb4_slovenian_ci | utf8mb4 | 228 | | Yes | 8 | PAD SPACE | | utf8mb4_sl_0900_ai_ci | utf8mb4 | 260 | | Yes | 0 | NO PAD | | utf8mb4_sl_0900_as_cs | utf8mb4 | 283 | | Yes | 0 | NO PAD | | utf8mb4_spanish2_ci | utf8mb4 | 238 | | Yes | 8 | PAD SPACE | | utf8mb4_spanish_ci | utf8mb4 | 231 | | Yes | 8 | PAD SPACE | | utf8mb4_sv_0900_ai_ci | utf8mb4 | 264 | | Yes | 0 | NO PAD | | utf8mb4_sv_0900_as_cs | utf8mb4 | 287 | | Yes | 0 | NO PAD | | utf8mb4_swedish_ci | utf8mb4 | 232 | | Yes | 8 | PAD SPACE | | utf8mb4_tr_0900_ai_ci | utf8mb4 | 265 | | Yes | 0 | NO PAD | | utf8mb4_tr_0900_as_cs | utf8mb4 | 288 | | Yes | 0 | NO PAD | | utf8mb4_turkish_ci | utf8mb4 | 233 | | Yes | 8 | PAD SPACE | | utf8mb4_unicode_520_ci | utf8mb4 | 246 | | Yes | 8 | PAD SPACE | | utf8mb4_unicode_ci | utf8mb4 | 224 | | Yes | 8 | PAD SPACE | | utf8mb4_vietnamese_ci | utf8mb4 | 247 | | Yes | 8 | PAD SPACE | | utf8mb4_vi_0900_ai_ci | utf8mb4 | 277 | | Yes | 0 | NO PAD | | utf8mb4_vi_0900_as_cs | utf8mb4 | 300 | | Yes | 0 | NO PAD | | utf8mb4_zh_0900_as_cs | utf8mb4 | 308 | | Yes | 0 | NO PAD | | utf8_bin | utf8 | 83 | | Yes | 1 | PAD SPACE | | utf8_croatian_ci | utf8 | 213 | | Yes | 8 | PAD SPACE | | utf8_czech_ci | utf8 | 202 | | Yes | 8 | PAD SPACE | | utf8_danish_ci | utf8 | 203 | | Yes | 8 | PAD SPACE | | utf8_esperanto_ci | utf8 | 209 | | Yes | 8 | PAD SPACE | | utf8_estonian_ci | utf8 | 198 | | Yes | 8 | PAD SPACE | | utf8_general_ci | utf8 | 33 | Yes | Yes | 1 | PAD SPACE | | utf8_general_mysql500_ci | utf8 | 223 | | Yes | 1 | PAD SPACE | | utf8_german2_ci | utf8 | 212 | | Yes | 8 | PAD SPACE | | utf8_hungarian_ci | utf8 | 210 | | Yes | 8 | PAD SPACE | | utf8_icelandic_ci | utf8 | 193 | | Yes | 8 | PAD SPACE | | utf8_latvian_ci | utf8 | 194 | | Yes | 8 | PAD SPACE | | utf8_lithuanian_ci | utf8 | 204 | | Yes | 8 | PAD SPACE | | utf8_persian_ci | utf8 | 208 | | Yes | 8 | PAD SPACE | | utf8_polish_ci | utf8 | 197 | | Yes | 8 | PAD SPACE | | utf8_romanian_ci | utf8 | 195 | | Yes | 8 | PAD SPACE | | utf8_roman_ci | utf8 | 207 | | Yes | 8 | PAD SPACE | | utf8_sinhala_ci | utf8 | 211 | | Yes | 8 | PAD SPACE | | utf8_slovak_ci | utf8 | 205 | | Yes | 8 | PAD SPACE | | utf8_slovenian_ci | utf8 | 196 | | Yes | 8 | PAD SPACE | | utf8_spanish2_ci | utf8 | 206 | | Yes | 8 | PAD SPACE | | utf8_spanish_ci | utf8 | 199 | | Yes | 8 | PAD SPACE | | utf8_swedish_ci | utf8 | 200 | | Yes | 8 | PAD SPACE | | utf8_tolower_ci | utf8 | 76 | | Yes | 1 | PAD SPACE | | utf8_turkish_ci | utf8 | 201 | | Yes | 8 | PAD SPACE | | utf8_unicode_520_ci | utf8 | 214 | | Yes | 8 | PAD SPACE | | utf8_unicode_ci | utf8 | 192 | | Yes | 8 | PAD SPACE | | utf8_vietnamese_ci | utf8 | 215 | | Yes | 8 | PAD SPACE | +----------------------------+----------+-----+---------+----------+---------+---------------+ 272 rows in set (0.00 sec)
MySQL 8.0 でデフォルトになった文字セット utf8mb4
UTF-8 エンコーディングの文字セットには utf8mb4 utf8mb3 utf8 があり、いずれも Unicode 文字集合で、符号化方式に UTF-8 が使われるようですが、使用されるバイト長が異なるようです。 また、utf8は utf8mb3 のエイリアスであり、将来的には utf8mb3 が削除される予定のため、utf8mb4を明示的に指定して使うように、とのことです。
utf8mb4 : Unicode 文字セットの UTF-8 エンコーディング。 文字ごとに 1 バイトから 4 バイトを使用します。 utf8mb3 : Unicode 文字セットの UTF-8 エンコーディング。 文字ごとに 1 バイトから 3 バイトを使用します。 utf8: utf8mb3 のエイリアス。
MySQL 8.0 でデフォルトになった照合順序 utf8mb4_0900_ai_ci
MySQL 5.7 では、照合順序のデフォルトは utf8mb4_general_ci でした。 これは、一般照合で、コードポイントでの照合になるようです。
MySQL 8.07 では、照合順序のデフォルトは utf8mb4_0900_ai_ci で、これは Unicode 照合アルゴリズム (UCA)バージョン 9.0.0 での照合になるようです。
また、名称の ai
はアクセントを区別しない、ci
は大文字小文字を区別しない、という意味を持つようです。
変更になった理由はわかりませんが、Unicode 照合アルゴリズム (UCA)を使うようにした、ということなのでしょうかね。
照合順序の確認
クライアントの環境によって collation_connection
と collation_server
が異なって挙動がおかしくなる場合があるようなので、最初に SET NAMES
でクライアントの設定を明示的に行います。
デフォルトだと utf8mb4_0900_ai_ci
になりますが、他の Collation を使いたい場合は、 SET NAMES utf8mb4 COLLATE utf8mb4_general_ci;
といった感じで COLLATE を指定します。
mysql> SET NAMES utf8mb4; Query OK, 0 rows affected (0.00 sec) mysql> SHOW VARIABLES LIKE '%collation_%'; +-------------------------------+--------------------+ | Variable_name | Value | +-------------------------------+--------------------+ | collation_connection | utf8mb4_0900_ai_ci | | collation_database | utf8mb4_0900_ai_ci | | collation_server | utf8mb4_0900_ai_ci | | default_collation_for_utf8mb4 | utf8mb4_0900_ai_ci | +-------------------------------+--------------------+ 4 rows in set (0.00 sec) mysql> SHOW VARIABLES LIKE '%character%'; +--------------------------+-------------------------------------------------------------------+ | Variable_name | Value | +--------------------------+-------------------------------------------------------------------+ | character_set_client | utf8mb4 | | character_set_connection | utf8mb4 | | character_set_database | utf8mb4 | | character_set_filesystem | binary | | character_set_results | utf8mb4 | | character_set_server | utf8mb4 | | character_set_system | utf8mb3 | | character_sets_dir | /rdsdbbin/oscar-8.0.mysql_aurora.3.04.2.0.47855.0/share/charsets/ | +--------------------------+-------------------------------------------------------------------+ 8 rows in set (0.00 sec) mysql> SELECT @@character_set_database, @@collation_database; +--------------------------+----------------------+ | @@character_set_database | @@collation_database | +--------------------------+----------------------+ | utf8mb4 | utf8mb4_0900_ai_ci | +--------------------------+----------------------+ 1 row in set (0.00 sec) mysql> SELECT 'A' = 'a'; +-----------+ | 'A' = 'a' | +-----------+ | 1 | +-----------+ 1 row in set (0.00 sec) mysql> SELECT 'あ' = 'ぁ'; +---------------+ | 'あ' = 'ぁ' | +---------------+ | 1 | +---------------+ 1 row in set (0.00 sec) mysql> SELECT 'か' = 'カ'; +---------------+ | 'か' = 'カ' | +---------------+ | 1 | +---------------+ 1 row in set (0.01 sec) mysql> SELECT 'か' = 'が'; +---------------+ | 'か' = 'が' | +---------------+ | 1 | +---------------+ 1 row in set (0.00 sec) mysql> SELECT '🍣' = '🍺'; +-----------+ | '?' = '?' | +-----------+ | 0 | +-----------+ 1 row in set (0.01 sec)
1がTrueで同一のものであることを表しています。 🍣と🍺の比較以外は同一のものとみなされています。
utf8mb4_general_ci
で試してみます。
mysql> SET NAMES utf8mb4 COLLATE utf8mb4_general_ci; Query OK, 0 rows affected (0.00 sec) mysql> SHOW VARIABLES LIKE '%character%'; +--------------------------+-------------------------------------------------------------------+ | Variable_name | Value | +--------------------------+-------------------------------------------------------------------+ | character_set_client | utf8mb4 | | character_set_connection | utf8mb4 | | character_set_database | utf8mb4 | | character_set_filesystem | binary | | character_set_results | utf8mb4 | | character_set_server | utf8mb4 | | character_set_system | utf8mb3 | | character_sets_dir | /rdsdbbin/oscar-8.0.mysql_aurora.3.04.2.0.47855.0/share/charsets/ | +--------------------------+-------------------------------------------------------------------+ 8 rows in set (0.01 sec) mysql> SHOW VARIABLES LIKE '%collation_%'; +-------------------------------+--------------------+ | Variable_name | Value | +-------------------------------+--------------------+ | collation_connection | utf8mb4_general_ci | | collation_database | utf8mb4_0900_ai_ci | | collation_server | utf8mb4_0900_ai_ci | | default_collation_for_utf8mb4 | utf8mb4_0900_ai_ci | +-------------------------------+--------------------+ 4 rows in set (0.00 sec) mysql> SELECT 'a' = 'A'; +-----------+ | 'a' = 'A' | +-----------+ | 1 | +-----------+ 1 row in set (0.01 sec) mysql> SELECT 'あ' = 'ぁ'; +---------------+ | 'あ' = 'ぁ' | +---------------+ | 0 | +---------------+ 1 row in set (0.00 sec) mysql> SELECT 'か' = 'が'; +---------------+ | 'か' = 'が' | +---------------+ | 0 | +---------------+ 1 row in set (0.00 sec) mysql> SELECT 'か' = 'カ'; +-------------+ | 'か' = 'カ' | +-------------+ | 0 | +-------------+ 1 row in set (0.00 sec) mysql> SELECT '🍣' = '🍺'; +-----------+ | '?' = '?' | +-----------+ | 1 | +-----------+ 1 row in set (0.01 sec)
こちらは、大文字小文字と🍣と🍺の比較は同一のものとみなされています。
WEIGHT_STRING()関数
WEIGHT_STRING() という関数の引数に文字列を指定し、その戻り値で、同じ文字であるかどうかを確認できるようです。この関数はデバッグ用のようです。
utf8mb4_0900_ai_ci
の場合で見てみます。
mysql> SET NAMES utf8mb4; Query OK, 0 rows affected (0.00 sec) mysql> SHOW VARIABLES LIKE '%collation_%'; +-------------------------------+--------------------+ | Variable_name | Value | +-------------------------------+--------------------+ | collation_connection | utf8mb4_0900_ai_ci | | collation_database | utf8mb4_0900_ai_ci | | collation_server | utf8mb4_0900_ai_ci | | default_collation_for_utf8mb4 | utf8mb4_0900_ai_ci | +-------------------------------+--------------------+ 4 rows in set (0.00 sec) mysql> SELECT 'a', HEX('a'), HEX(WEIGHT_STRING('a')); +---+----------+-------------------------+ | a | HEX('a') | HEX(WEIGHT_STRING('a')) | +---+----------+-------------------------+ | a | 61 | 1C47 | +---+----------+-------------------------+ 1 row in set (0.00 sec) mysql> SELECT 'A', HEX('A'), HEX(WEIGHT_STRING('A')); +---+----------+-------------------------+ | A | HEX('A') | HEX(WEIGHT_STRING('A')) | +---+----------+-------------------------+ | A | 41 | 1C47 | +---+----------+-------------------------+ 1 row in set (0.00 sec) mysql> SELECT 'あ', HEX('あ'), HEX(WEIGHT_STRING('あ')); +-----+------------+---------------------------+ | あ | HEX('あ') | HEX(WEIGHT_STRING('あ')) | +-----+------------+---------------------------+ | あ | E38182 | 3D5A | +-----+------------+---------------------------+ 1 row in set (0.00 sec) mysql> SELECT 'ぁ', HEX('ぁ'), HEX(WEIGHT_STRING('ぁ')); +-----+------------+---------------------------+ | ぁ | HEX('ぁ') | HEX(WEIGHT_STRING('ぁ')) | +-----+------------+---------------------------+ | ぁ | E38181 | 3D5A | +-----+------------+---------------------------+ 1 row in set (0.00 sec) mysql> SELECT '🍣', HEX('🍣'), HEX(WEIGHT_STRING('🍣')); +------+----------+-------------------------+ | ? | HEX('?') | HEX(WEIGHT_STRING('?')) | +------+----------+-------------------------+ | 🍣 | F09F8DA3 | 130C | +------+----------+-------------------------+ 1 row in set (0.00 sec) mysql> SELECT '🍺', HEX('🍺'), HEX(WEIGHT_STRING('🍺')); +------+----------+-------------------------+ | ? | HEX('?') | HEX(WEIGHT_STRING('?')) | +------+----------+-------------------------+ | 🍺 | F09F8DBA | 1323 | +------+----------+-------------------------+ 1 row in set (0.00 sec)
utf8mb4_0900_ai_ci
の場合、上記の比較では🍣と🍺以外は同一の値であることが確認できました。
まとめ
MySQL 8.0 で、 Collation や Charset が MySQL 5.7 から変更になっていたので、挙動を確認してみたのと、文字セット・照合順序についても少し調べて簡単に概要を記載しました。
utf8mb4_0900_ai_ci
では大文字・小文字、濁音・半濁音も同一とみなされるので、検索時のヒット率は上がりそうです。MySQL 5.7 の utf8mb4_general_ci
とは異なる結果が得られるので注意は必要そうです。
参考
- MySQL :: MySQL 8.0 Reference Manual :: 12.1 Character Sets and Collations in General
- MySQL :: MySQL 8.0 リファレンスマニュアル :: 10.9 Unicode のサポート
- 第157回 MySQLのデフォルトcollationの注意点 | gihyo.jp
- UTF-8 - Wikipedia
- Unicode - Wikipedia
- https://qiita.com/hamachi4708/items/b6acc3cef20bea29bd3b:ttile
- MySQL接続のcollation不整合の原因と対策
- http://mysqlserverteam.com/sushi-beer-an-introduction-of-utf8-support-in-mysql-8-0/
- 10.14 文字セットへの照合順序の追加
- 10.14.1 照合順序の実装タイプ
- とほほの文字コード入門 - とほほのWWW入門