Я пытаюсь выяснить, какую сортировку я должен использовать для различных типов данных. 100% содержимого, которое я буду хранить, представлено пользователем.
Я понимаю, что вместо UTF-8 Binary я должен использовать UTF-8 General CI (без учета регистра). Однако я не могу найти четкое различие между UTF-8 General CI и UIF-8 Unicode CI.
В общем случае utf8_general_ci быстрее, чем utf8_unicode_ci, но менее корректен.
Вот разница:
Для любого набора символов Юникода операции , выполняемые с использованием сопоставления _general_ci, быстрее, чем операции сортировки _unicode_ci. Например, сравнение для сортировки utf8_general_ci выполняется быстрее, но немного менее корректно, чем сравнение для utf8_unicode_ci. Причиной этого является то, что utf8_unicode_ci поддерживает отображения, такие как разложения; то есть, когда один символ сравнивается с комбинациями других символов. Например, на немецком и некоторых других языках "ß" равно "ss". utf8_unicode_ci также поддерживает сжатие и игнорируемые символы. utf8_general_ci - это устаревшая сортировка, которая не поддерживает расширения, сокращения или игнорируемые символы. Он может проводить только взаимно однозначные сравнения между символами.
Цитата из: http://dev.mysql.com/doc/refman/5.0/en/charset-unicode-sets.html
Для более подробного объяснения, пожалуйста, прочитайте следующую статью на форумах MySQL: http://forums.mysql.com/read.php?103,187048,188748
Что касается utf8_bin: Оба utf8_general_ci и utf8_unicode_ci выполняют сравнение без учета регистра. В constrast utf8_bin чувствителен к регистру (среди других различий), поскольку он сравнивает двоичные значения символов.
Вы также должны знать, что с utf8_general_ci при использовании поля varchar в качестве уникального или первичного вставки индекса 2 значения, такие как 'a' и 'á', будут давать повторяющуюся ключевую ошибку.
utf8_unicode_ci
utf8_bin
сравнивает бит вслепую. Нет складчатости, без снятия акцента.utf8_general_ci
сравнивает один байт с одним байтом. Это делает разборку фальцовки и акцентов, но не 2-символьные сравнения: ij
не равно ij
в этом сопоставлении.utf8_*_ci
- это набор правил, специфичных для языка, но в противном случае unicode_ci
. Некоторые специальные случаи: Ç
, Č
, ch
, ll
utf8_unicode_ci
следует за старым стандартом Unicode для сравнения. ij
= ij
, но ae
!= æ
utf8_unicode_520_ci
следует за новым стандартом Unicode. ae
= æ
См. таблицу сопоставлений для получения подробной информации о том, что равнозначно тому, что содержится в различных сортировках utf8.
utf8
, как определено MySQL, ограничено 1- 3-байтовыми utf8-кодами. Это исключает Эмоджи и некоторых китайцев. Поэтому вы действительно должны переключиться на utf8mb4
, если хотите выйти далеко за пределы Европы.
Вышеуказанные пункты относятся к utf8mb4
после подходящего изменения правописания. Вперёд, utf8mb4
и utf8mb4_unicode_520_ci
являются предпочтительными.
В самом деле, я тестировал сохранение значений, таких как "é" и "e" в столбце с индексом уникальный, и они вызывают дублируемую ошибку как для "utf8_unicode_ci", так и "utf8_general_ci". Вы можете сохранить их только в столбце "utf8_bin".
И mysql docs (в http://dev.mysql.com/doc/refman/5.7/en/charset-applications.html) предлагают в своих примерах настройку 'utf8_general_ci'.
[mysqld]
character-set-server=utf8
collation-server=utf8_general_ci
Принятый ответ устарел.
Если вы используете MySQL 5.5. 3+, используйте utf8mb4_unicode_ci
вместо utf8_unicode_ci
чтобы символы, набранные вашими пользователями, не utf8mb4_unicode_ci
ошибок.
Например, utf8mb4
поддерживает эмодзи, тогда как utf8
может дать вам сотни ошибок, связанных с кодировкой, например:
Incorrect string value: '\xF0\x9F\x98\x81… for column 'data at row 1
utf8
используйтеutf8mb4
вместо полной поддержки UTF-8. Комментировать здесь, потому что ответы на этот популярный вопрос не решают эту проблему. mathiasbynens.be/notes/mysql-utf8mb4