とみたまさひろ
2019-12-18
ニフクラエンジニアミートアップ
#nifcloud_emup
困る!
mysql> set @a='令和', @b='令和';
mysql> select @a, @b, hex(@a), hex(@b);
+--------+--------+--------------+--------------+
| @a | @b | hex(@a) | hex(@b) |
+--------+--------+--------------+--------------+
| 令和 | 令和 | E4BBA4E5928C | EFA6A8E5928C |
+--------+--------+--------------+--------------+
mysql> select @a=@b;
+-------+
| @a=@b |
+-------+
| 1 | ← ❗❗
+-------+
一致
😊
良かったですね
異体字セレクタ
困る!
mysql> set @a='令和', @b='令󠄁和', @c='令󠄂和';
mysql> select hex(@a), hex(@b), hex(@c)\G
*************************** 1. row ***************************
hex(@a): E4BBA4E5928C
hex(@b): E4BBA4F3A08481E5928C
hex(@c): E4BBA4F3A08482E5928C
mysql> select @a=@b, @b=@c;
+-------+-------+
| @a=@b | @b=@c |
+-------+-------+
| 1 | 1 | ← ❗❗
+-------+-------+
※都合により同じ字体に見えてます
一致
😊
良かったですね
明治(U+660E U+6CBB) | ㍾(U+337E) |
大正(U+5927 U+6B63) | ㍽(U+337D) |
昭和(U+662D U+548C) | ㍼(U+337C) |
平成(U+5E73 U+6210) | ㍻(U+337B) |
令和(U+4EE4 U+548C) | ㋿(U+32FF) |
mysql> select '明治'='㍾', '大正'='㍽', '昭和'='㍼',
-> '平成'='㍻', '令和'='㋿'\G
*************************** 1. row ***************************
'明治'='㍾': 1 ← 一致❗
'大正'='㍽': 1 ← 一致❗
'昭和'='㍼': 1 ← 一致❗
'平成'='㍻': 1 ← 一致❗
'令和'='㋿': 0 ← 不一致❗
😇
残念
文字毎にWeightという値が定義されている
Weightが等しいなら等しい文字
Unicode Collation Algorithm (UCA)
https://unicode.org/reports/tr10/tr10-34.html
Default Unicode Collation Element Table (DUCET)
https://www.unicode.org/Public/UCA/9.0.0/allkeys.txt
↑計算で求められない文字ごとの値
[.FB40.0020.0002][.(CP | 0x8000).0000.0000]
→ [.FB40.0020.0002][.CEE4.0000.0000]
F9A8 ; [.FB40.0020.0002][.CEE4.0000.0000]
Weightが一致するから等しい
異体字セレクタ
異体字セレクタはDUCETにある
E0101 ; [.0000.0000.0000] # VARIATION SELECTOR-18
E0102 ; [.0000.0000.0000] # VARIATION SELECTOR-19
UCAではすべてゼロの文字は無視して比較
→ 一致
㍾ / ㍽ / ㍼ / ㍻ / ㋿
平成 [.FB40.0020.0002][.DE73.0000.0000][.FB40.0020.0002][.E210.0000.0000]
㍻ [.FB40.0020.001C][.DE73.0000.0000][.FB40.0020.001C][.E210.0000.0000]
ちょっと違う… 🤔
MySQLのデフォルトのCollation
要素 | 意味 |
---|---|
utf8mb4 | 4バイトUTF-8 |
0900 | Unicode 9.0.0 |
ai | アクセントの違いを無視 |
ci | 大文字小文字の違いを無視 |
ci
の場合はWeightの3番目を無視
ci
の場合はWeightの3番目を無視
平成 [.FB40.0020.0002][.DE73.0000.0000][.FB40.0020.0002][.E210.0000.0000]
㍻ [.FB40.0020.001C][.DE73.0000.0000][.FB40.0020.001C][.E210.0000.0000]
3番目を無視すると
平成 [.FB40.0020. ][.DE73.0000. ][.FB40.0020. ][.E210.0000. ]
㍻ [.FB40.0020. ][.DE73.0000. ][.FB40.0020. ][.E210.0000. ]
一致
そもそも「㋿」がDUCETに無い!
「㋿」はUnicode 9.0.0 に無い!
「㋿」はUnicode 12.1.0 で追加
12.1 は「㋿」のためだけに 5/7 にリリース
Unicode 12.1 adds exactly one character, for a total of 137,929 characters.
The new character added to Version 12.1 is:
U+32FF SQUARE ERA NAME REIWA
Version 12.1 adds that single character to enable software to be rapidly updated to support the new Japanese era name in calendrical systems and date formatting. The new Japanese era name was officially announced on April 1, 2019, and is effective as of May 1, 2019.
MySQL の Unicode 12.1 対応はいつだろう… 🤔
要素 | 意味 |
---|---|
utf8mb4 | 4バイトUTF-8 |
ja | 言語 |
0900 | Unicode 9.0.0 |
as | アクセント違いは別の文字 |
cs | 大文字小文字は別の文字 |
ks | 平仮名と片仮名は別の文字 |
比較 | ai_ci | as_ci | as_cs | ja as_cs | ja as_cs_ks | bin |
---|---|---|---|---|---|---|
A =a
|
◯ | ◯ | × | × | × | × |
A =A
|
◯ | ◯ | × | ◯ | ◯ | × |
A =a
|
◯ | ◯ | × | × | × | × |
あ =ぁ
|
◯ | ◯ | × | × | × | × |
あ =ア
|
◯ | ◯ | × | ◯ | × | × |
は =ば =ぱ
|
◯ | × | × | × | × | × |
1 =①
|
◯ | ◯ | × | × | × | × |
令 =令
|
◯ | ◯ | ◯ | × | × | × |
令 =令󠄂
|
◯ | ◯ | ◯ | ◯ | ◯ | × |
平成 =㍻
|
◯ | ◯ | × | × | × | × |
mysql> select c,hex(c) from t order by c collate utf8mb4_0900_as_cs;
+------+--------+
| c | hex(c) |
+------+--------+
| 亜 | E4BA9C |
| 伊 | E4BC8A |
| 奥 | E5A5A5 |
| 宇 | E5AE87 |
| 栄 | E6A084 |
+------+--------+
mysql> select c,hex(c) from t order by c collate utf8mb4_ja_0900_as_cs;
+------+--------+
| c | hex(c) |
+------+--------+
| 亜 | E4BA9C |
| 伊 | E4BC8A |
| 宇 | E5AE87 |
| 栄 | E6A084 |
| 奥 | E5A5A5 |
+------+--------+
mysql> select c from t2 order by c collate utf8mb4_ja_0900_as_cs;
+--------+
| c |
+--------+
| かー |
| かあ |
| かい |
| きあ |
| きー |
| きい |
| くあ |
| くい |
| くー |
+--------+