web-dev-qa-db-ja.com

MySQLギリシャ語の重複エントリ

一意の列があり、ΑγάθηΑγαθή(異なる)を追加すると、#1062 - Duplicate entry 'Αγαθή' for key 'Word'と表示されます。照合順序はutf8_general_ciに設定されています。より良い照合はありますか?

1
Almis

いくつかのutf8利用可能な照合:

mysql> SELECT * FROM information_schema.collations WHERE character_set_name = 'utf8';
+--------------------------+--------------------+-----+------------+-------------+---------+
| COLLATION_NAME           | CHARACTER_SET_NAME | ID  | IS_DEFAULT | IS_COMPILED | SORTLEN |
+--------------------------+--------------------+-----+------------+-------------+---------+
| utf8_general_ci          | utf8               |  33 | Yes        | Yes         |       1 |
| utf8_bin                 | utf8               |  83 |            | Yes         |       1 |
| utf8_unicode_ci          | utf8               | 192 |            | Yes         |       8 |
| utf8_icelandic_ci        | utf8               | 193 |            | Yes         |       8 |
| utf8_latvian_ci          | utf8               | 194 |            | Yes         |       8 |
| utf8_romanian_ci         | utf8               | 195 |            | Yes         |       8 |
| utf8_slovenian_ci        | utf8               | 196 |            | Yes         |       8 |
| utf8_polish_ci           | utf8               | 197 |            | Yes         |       8 |
| utf8_estonian_ci         | utf8               | 198 |            | Yes         |       8 |
| utf8_spanish_ci          | utf8               | 199 |            | Yes         |       8 |
| utf8_swedish_ci          | utf8               | 200 |            | Yes         |       8 |
| utf8_turkish_ci          | utf8               | 201 |            | Yes         |       8 |
| utf8_czech_ci            | utf8               | 202 |            | Yes         |       8 |
| utf8_danish_ci           | utf8               | 203 |            | Yes         |       8 |
| utf8_lithuanian_ci       | utf8               | 204 |            | Yes         |       8 |
| utf8_slovak_ci           | utf8               | 205 |            | Yes         |       8 |
| utf8_spanish2_ci         | utf8               | 206 |            | Yes         |       8 |
| utf8_roman_ci            | utf8               | 207 |            | Yes         |       8 |
| utf8_persian_ci          | utf8               | 208 |            | Yes         |       8 |
| utf8_esperanto_ci        | utf8               | 209 |            | Yes         |       8 |
| utf8_hungarian_ci        | utf8               | 210 |            | Yes         |       8 |
| utf8_sinhala_ci          | utf8               | 211 |            | Yes         |       8 |
| utf8_german2_ci          | utf8               | 212 |            | Yes         |       8 |
| utf8_croatian_ci         | utf8               | 213 |            | Yes         |       8 |
| utf8_unicode_520_ci      | utf8               | 214 |            | Yes         |       8 |
| utf8_vietnamese_ci       | utf8               | 215 |            | Yes         |       8 |
| utf8_general_mysql500_ci | utf8               | 223 |            | Yes         |       1 |
+--------------------------+--------------------+-----+------------+-------------+---------+
27 rows in set (0.00 sec)

これらはギリシャ語の文字列を比較するための合理的な方法です。

mysql> SET NAMES utf8;
Query OK, 0 rows affected (0.00 sec)

mysql> SELECT 'Αγάθη' = 'Αγαθή' COLLATE utf8_general_ci;
+-----------------------------------------------------+
| 'Αγάθη' = 'Αγαθή' COLLATE utf8_general_ci           |
+-----------------------------------------------------+
|                                                   1 |
+-----------------------------------------------------+
1 row in set (0.00 sec)

mysql> SELECT 'Αγάθη' = 'Αγαθή' COLLATE utf8_unicode_ci;
+-----------------------------------------------------+
| 'Αγάθη' = 'Αγαθή' COLLATE utf8_unicode_ci           |
+-----------------------------------------------------+
|                                                   1 |
+-----------------------------------------------------+
1 row in set (0.00 sec)

mysql> SELECT 'Αγάθη' = 'Αγαθή' COLLATE utf8_unicode_520_ci;
+---------------------------------------------------------+
| 'Αγάθη' = 'Αγαθή' COLLATE utf8_unicode_520_ci           |
+---------------------------------------------------------+
|                                                       1 |
+---------------------------------------------------------+
1 row in set (0.00 sec)

mysql> SELECT 'Αγάθη' = 'Αγαθή' COLLATE utf8_bin;
+----------------------------------------------+
| 'Αγάθη' = 'Αγαθή' COLLATE utf8_bin           |
+----------------------------------------------+
|                                            0 |
+----------------------------------------------+
1 row in set (0.00 sec)

mysql> SELECT BINARY 'Αγάθη' = 'Αγαθή';
+------------------------------------+
| BINARY 'Αγάθη' = 'Αγαθή'           |
+------------------------------------+
|                                  0 |
+------------------------------------+
1 row in set (0.01 sec)

ご覧のとおり、utf8bin照合はそれらを異なるものと見なし、もちろんBINARY比較を行います。

Utf8またはutf8mb4には特定のギリシャ語の照合順序はないようですが、1バイトのISO 8859-7実装「ギリシャ語」もあり、いくつかの追加の照合順序があります。

mysql> SELECT * FROM information_schema.collations WHERE character_set_name = 'greek';
+------------------+--------------------+----+------------+-------------+---------+
| COLLATION_NAME   | CHARACTER_SET_NAME | ID | IS_DEFAULT | IS_COMPILED | SORTLEN |
+------------------+--------------------+----+------------+-------------+---------+
| greek_general_ci | greek              | 25 | Yes        | Yes         |       1 |
| greek_bin        | greek              | 70 |            | Yes         |       1 |
+------------------+--------------------+----+------------+-------------+---------+
2 rows in set (0.00 sec)

ギリシャ語はまったくわからないので、列のデフォルトのエンコーディングと照合順序を変更する場合は、ギリシャ語とギリシャ語の両方で予期しない順序付け/比較/グループ化の結果が生じる可能性があるため、必ず再確認してくださいすべてのクエリ他の言語(例:utf8絵文字の保存は許可されていません。 utf8mb4_unicode_ciおよびutf8mb4_unicode_520_ciはそれらを異なる方法で比較します)、そしてあなたが望むかもしれないものは呼び出しの文脈に大きく依存します。

2
jynus

utf8_bin照合順序を使用してみてください。例:これはその効果を示します:

SELECT _utf8 'Αγάθη' = _utf8 'Αγαθή' COLLATE utf8_bin;
0
codeit