UTF-8: генерал? Бен? Unicode?

261

Я пытаюсь выяснить, какую сортировку я должен использовать для различных типов данных. 100% содержимого, которое я буду хранить, представлено пользователем.

Я понимаю, что вместо UTF-8 Binary я должен использовать UTF-8 General CI (без учета регистра). Однако я не могу найти четкое различие между UTF-8 General CI и UIF-8 Unicode CI.

  • Должен ли я хранить содержимое, представленное пользователем, в UTF-8 General или UTF-8 Unicode CI-столбцах?
  • Каким типом данных будет использоваться UTF-8 Binary для?
  • 13
    Примечание, но вместо utf8 используйте utf8mb4 вместо полной поддержки UTF-8. Комментировать здесь, потому что ответы на этот популярный вопрос не решают эту проблему. mathiasbynens.be/notes/mysql-utf8mb4
  • 0
    Если вы хотите сворачивать регистр, но чувствительность к акценту, пожалуйста, отправьте запрос на bugs.mysql.com .
Показать ещё 1 комментарий
Теги:
utf-8
collation

5 ответов

296
Лучший ответ

В общем случае 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 чувствителен к регистру (среди других различий), поскольку он сравнивает двоичные значения символов.

  • 2
    Я думаю, что если у вас нет веских причин использовать _unicode_ci, то используйте _general_ci.
  • 4
    Это действительно не отвечает на вопрос в глубине, хотя. В чем разница между этими сопоставлениями?
Показать ещё 4 комментария
85

Вы также должны знать, что с utf8_general_ci при использовании поля varchar в качестве уникального или первичного вставки индекса 2 значения, такие как 'a' и 'á', будут давать повторяющуюся ключевую ошибку.

  • 3
    Спасибо, это полезно, чтобы избежать подобных имен пользователей (например, если существует "jose", я бы не хотел, чтобы кто-то еще создал пользователя "josé"). Примечание: это также верно для большинства параметров сортировки utf8 (кроме utf8_bin). Самый надежный / самый безопасный / самый полный - utf8_unicode_ci
  • 2
    Я использую utf8_bin, где я хочу, чтобы Хосе и Хосе были выделены в индексе. Например, столбец, в котором записываются операции поиска / замены, где пользователь, возможно, решил поискать josé и заменить его на jose. (Я пишу программу для работы с электронными таблицами)
24
  • 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 являются предпочтительными.

  • utf16 и utf32 - варианты на utf8; для них практически не используется.
  • ucs2 ближе к "Юникод", чем "utf8"; для него практически не используется.
  • 1
    «Оставайтесь с нами»: сопоставления 8.0 показывают, как различные символы, дифтонги и т. Д. Сравниваются в сопоставлениях 8.0 utf8mb4; UTF8 в основном то же самое.
  • 0
    И 8,0 сопоставления работают значительно быстрее, чем 5.x.
6

В самом деле, я тестировал сохранение значений, таких как "é" и "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
  • 1
    Я сделал быструю проверку на это, и это кажется точным. Оба сопоставления ведут себя одинаково, когда дело доходит до уникального ключа в столбце и значений с тильдами и тому подобным.
  • 0
    @MirroredFate Хорошо, я должен добавить, что столбец должен иметь уникальный индекс, вызывающий эту ошибку. Это подразумевает в моем ответе.
0

Принятый ответ устарел.

Если вы используете 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

Ещё вопросы

Сообщество Overcoder
Наверх
Меню