Closed6

MySQLのCharacter Sets, Collations, Unicodeのページを読んでみる その2

suzuki-navisuzuki-navi

https://dev.mysql.com/doc/refman/8.1/en/charset-collate.html

COLLATEはSQLのいろいろな場所で使える。

SELECT k
FROM t1
ORDER BY k COLLATE latin1_german2_ci;

SELECT k COLLATE latin1_german2_ci AS k1
FROM t1
ORDER BY k1;

SELECT k
FROM t1
GROUP BY k COLLATE latin1_german2_ci;

SELECT MAX(k COLLATE latin1_german2_ci)
FROM t1;

SELECT DISTINCT k COLLATE latin1_german2_ci
FROM t1;

SELECT *
FROM t1
WHERE _latin1 'Müller' COLLATE latin1_german2_ci = k;

SELECT *
FROM t1
WHERE k LIKE _latin1 'Müller' COLLATE latin1_german2_ci;

SELECT k
FROM t1
GROUP BY k
HAVING k = _latin1 'Müller' COLLATE latin1_german2_ci;
suzuki-navisuzuki-navi

https://dev.mysql.com/doc/refman/8.1/en/charset-binary-collations.html

binaryは大文字小文字の情報がないが、utf8mb4には大文字小文字の情報があり、collationでバイナリ(utf8mb4_binなど)を指定しても大文字小文字変換ができる。

MySQL [test]> select upper('a');
+------------+
| upper('a') |
+------------+
| A          |
+------------+
1 row in set (0.000 sec)

MySQL [test]> select upper(_binary'a');
+-------------------+
| upper(_binary'a') |
+-------------------+
| a                 |
+-------------------+
1 row in set (0.001 sec)

MySQL [test]> select upper(_utf8mb4'a' collate utf8mb4_bin);
+----------------------------------------+
| upper(_utf8mb4'a' collate utf8mb4_bin) |
+----------------------------------------+
| A                                      |
+----------------------------------------+

collationは順序付けや比較で使う。

MySQL [test]> select 'a' < 'B';
+-----------+
| 'a' < 'B' |
+-----------+
|         1 |
+-----------+

MySQL [test]> select 'a' collate utf8mb3_bin < 'B';
+-------------------------------+
| 'a' collate utf8mb3_bin < 'B' |
+-------------------------------+
|                             0 |
+-------------------------------+
MySQL [test]> select 'a' = 'A';
+-----------+
| 'a' = 'A' |
+-----------+
|         1 |
+-----------+

MySQL [test]> select 'a' = 'A' collate utf8mb3_bin;
+-------------------------------+
| 'a' = 'A' collate utf8mb3_bin |
+-------------------------------+
|                             0 |
+-------------------------------+

MySQL [test]> select 'a' collate utf8mb3_bin = 'A';
+-------------------------------+
| 'a' collate utf8mb3_bin = 'A' |
+-------------------------------+
|                             0 |
+-------------------------------+
suzuki-navisuzuki-navi

https://dev.mysql.com/doc/refman/8.1/en/charset-collation-effect.html

collationで比較結果が変わる例を自分で考えてみた。

韓国語の文字であるハングルは1文字をコードポイント1つで表現する方法とパーツを分解してコードポイント2つ以上で表現する方法があり、どちらで表現してもまったく同じ見た目の文字として表示される。

  • 커피 は文字数2、コードポイント数2、UTF8のバイト数6
  • 커피 は文字数2、コードポイント数4、UTF8のバイト数12

私の環境のターミナルにコピペすると文字化けてしまうのだが、以下のような結果になった。HEX関数で確認するとちゃんと認識はできていそう。collate utf8mb4_0900_ai_ciを指定したら同一視された。

MySQL [test]> select hex('커피'), hex('ᄏᄑ');
+---------------+--------------------------+
| hex('커피')   | hex('커 ')            |
+---------------+--------------------------+
| ECBBA4ED94BC  | E1848FE185A5E18491E185B5 |
+---------------+--------------------------+

MySQL [test]> select '커피' = 'ᄏᄑ';
+---------------------------+
| '커피' = '커 '         |
+---------------------------+
|                         0 |
+---------------------------+

MySQL [test]> select _utf8mb4'커피' = _utf8mb4'ᄏᄑ' collate utf8mb4_0900_ai_ci;
+----------------------------------------------------------------------+
| _utf8mb4'커피' = _utf8mb4'커 ' collate utf8mb4_0900_ai_ci         |
+----------------------------------------------------------------------+
|                                                                    1 |
+----------------------------------------------------------------------+
このスクラップは2023/08/11にクローズされました