UTF-8: Общие? Бен? Unicode?

Я пытаюсь выяснить, какую сортировку я должен использовать для различных типов данных. 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 для?

Ответ 1

В общем случае 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

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

Ответ 3

  • 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"; для него практически не используется.

Ответ 4

В самом деле, я тестировал сохранение значений, таких как "é" и "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

Ответ 5

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

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