Почему мой экземпляр MySQL думает, что «ī» и «i» - равные символы? - PullRequest
3 голосов
/ 14 мая 2019

Я сталкиваюсь с проблемами ограничения уникальности в MySQL.У меня есть два разных символа:

  • ī, который является десятичным ASCII 299
  • i, который является десятичным ASCII 109

Почему MySQL видитэти как равные?Когда я запускаю следующее:

SELECT STRCMP('ī', 'i')

Я получаю возвращаемое значение 0.

За запрос, вот некоторая информация о моей среде:

mysql> SELECT @@character_set_database, @@collation_database;
+--------------------------+----------------------+
| @@character_set_database | @@collation_database |
+--------------------------+----------------------+
| utf8mb4                  | utf8mb4_unicode_ci   |
+--------------------------+----------------------+

Ответы [ 2 ]

6 голосов
/ 14 мая 2019

В вашей базе данных по умолчанию используется сопоставление без учета регистра : это часть ci в конце @@collation_database. В этом сопоставлении для большинства языков сложены диакритические знаки. Из документов:

Чтобы дополнительно проиллюстрировать, следующие равенства выполняются как в utf8_general_ci, так и в utf8_unicode_ci (эффект этого в сравнениях или поисках см. В разделе 10.8.6, «Примеры эффекта сопоставления»):

А = A
Ö = O
Ü = U

https://dev.mysql.com/doc/refman/8.0/en/charset-unicode-sets.html

Если вы не нашли причины для этого, я бы предложил изменить это значение по умолчанию.

3 голосов
/ 14 мая 2019

Символы равны, если они определены как равные в текущем сопоставлении.

Строки имеют набор символов и определенные параметры сортировки. Если строка происходит из таблицы, таблица или столбец определяет параметры сортировки.

Если строка является литералом, который вы используете в выражении SQL (как в вашем примере), для параметров сортировки по умолчанию используется значение сеанса для параметров MySQL character_set_connection и collation_connection.

Вы можете переопределить значения сеанса для данного строкового литерала, используя предложение COLLATE:

mysql> SELECT STRCMP('ī', 'i' COLLATE utf8mb4_bin);
+---------------------------------------+
| STRCMP('ī', 'i' COLLATE utf8mb4_bin)  |
+---------------------------------------+
|                                     1 |
+---------------------------------------+

См. https://dev.mysql.com/doc/refman/8.0/en/charset-introducer.html

...