[sisyphus] странное и некрасивое поведение utf8 в паре rails/mysql

Mikhail Yakshin greycat на altlinux.org
Вс Июн 28 10:16:19 MSD 2009


> MySQL продолжает упорствовать в своих заблуждениях.
>
[...]

>  Dict.find_by_word "ᾆδω"
> => #<Dict id: 2622, parent_id: nil, group_id: nil, variant_id: nil, word: "ἄδω"
>
> но  "ᾆδω"  это не "ἄδω" совсем.
>
> Интересно, может быть постгрес будет проще настроить?

Это unicode case-insensitive (ci) collation, который вполне себе
корректно отрабатывает. С точки зрения unicode - это два символа,
которые равны по sort values - т.к. и "ᾆ", и "ἄ" равны просто "α":

mysql> select 'ᾆ'='α';
+------------+
| 'ᾆ'='α'    |
+------------+
|          1 |
+------------+

Это в целом полезный механизм - например, пользователь может написать
"елка", и оно из-за этого case insensitivity смэтчится со словами
"ёлка", "Елка" или "Ёлка", которые найдутся в базе.

Более подробно об этом можно почитать в руководстве MySQL:
http://dev.mysql.com/doc/refman/5.0/en/case-sensitivity.html

Quick solution, если надо просто отключить любые case- и sort-
sensitivity - использовать тип BINARY (или collation utf8_bin). Их
можно поставить на БД целиком, на таблицы/поля/переменные или даже
индивидуальные сравнения:

mysql> select 'ᾆ' COLLATE utf8_bin='α';
+-----------------------------+
| 'ᾆ' COLLATE utf8_bin='α'    |
+-----------------------------+
|                           0 |
+-----------------------------+

Postgresql в данном случае будет вести себя точно так же - эти вещи
(классы эквивалентности по sort value для различных characters)
прописаны в стандарте unicode.

P.S. Вопрос, видимо, всё-таки не имеет отношения к sisyphus@ -
предлагаю переместиться в личную почту для дальнейших обсуждений, если
таковые будут иметь место.

-- 
WBR, Mikhail Yakshin


Подробная информация о списке рассылки Sisyphus