Ответ 1
Эти два сопоставления предназначены для кодировки символов UTF-8. Различия заключаются в том, как текст сортируется и сравнивается.
Примечание. Начиная с MySQL 5.5.3, вы должны использовать utf8mb4
, а не utf8
. Они оба ссылаются на кодировку UTF-8, но более старый utf8
имел специфичное для MySQL ограничение, запрещающее использование символов с номерами выше 0xFFFD.
Ключевые отличия
utf8mb4_unicode_ci
основан на официальных правилах Unicode для универсальной сортировки и сравнения, которая точно сортирует по широкому спектру языков.utf8mb4_general_ci
- это упрощенный набор правил сортировки, цель которого - сделать все возможное, используя множество ярлыков, предназначенных для повышения скорости. Он не соответствует правилам Юникода и может привести к нежелательной сортировке или сравнению в некоторых ситуациях, например при использовании определенных языков или символов.На современных серверах это повышение производительности будет практически незначительным. Он был разработан в то время, когда серверы имели небольшую долю производительности ЦП современных компьютеров.
Примечание: в настоящее время существует обновленная версия utf8mb4_unicode_ci
под названием utf8mb4_0900_ai_ci
- она основана на изменениях в Unicode версии 9.0, а также, по-видимому, быстрее. Он принимает новую схему именования, согласно которой 0900
является версией Unicode, а ai
означает нечувствительный к акценту - как и предыдущий utf8mb4_unicode_ci
, ударения в письмах не считаются значительными.
Преимущества utf8mb4_unicode_ci
перед utf8mb4_general_ci
utf8mb4_unicode_ci
, который использует правила Unicode для сортировки и сравнения, использует довольно сложный алгоритм для правильной сортировки в широком диапазоне языков и при использовании широкого диапазона специальных символов. Эти правила должны учитывать языковые соглашения; не каждый сортирует своих персонажей в том, что мы назвали бы "алфавитным порядком".
Что касается латиницы (то есть "европейских") языков, между сортировкой Unicode и упрощенной сортировкой utf8mb4_general_ci
в MySQL нет большой разницы, но есть еще несколько отличий:
Например, параметры сортировки Unicode сортируют "ß", например, "ss", и "Œ", например "OE", как обычно хотят люди, использующие эти символы, тогда как
utf8mb4_general_ci
сортирует их как одиночные символы (предположительно, как "s" и "e"). "соответственно).Некоторые символы Юникода определены как игнорируемые, что означает, что они не должны учитываться в порядке сортировки, и сравнение должно перейти к следующему символу.
utf8mb4_unicode_ci
обрабатывает их правильно.
В нелатинских языках, таких как азиатские языки или языки с разными алфавитами, может быть намного больше различий между сортировкой Unicode и упрощенной сортировкой utf8mb4_general_ci
. Пригодность utf8mb4_general_ci
будет сильно зависеть от используемого языка. Для некоторых языков это будет неадекватно.
Что вы должны использовать?
Почти наверняка нет причин использовать utf8mb4_general_ci
, поскольку мы оставили точку, когда скорость процессора достаточно низкая, чтобы разница в производительности была важной. Ваша база данных почти наверняка будет ограничена другими узкими местами, кроме этой.
В прошлом некоторые люди рекомендовали использовать utf8mb4_general_ci
, за исключением случаев, когда точная сортировка должна была стать достаточно важной, чтобы оправдать снижение производительности. Сегодня эта производительность практически исчезла, и разработчики относятся к интернационализации более серьезно.
Можно привести аргумент, что если скорость важнее для вас, чем точность, вы можете вообще не выполнять никакой сортировки. Тривиально сделать алгоритм быстрее, если вам не нужно, чтобы он был точным. Таким образом, utf8mb4_general_ci
- это компромисс, который, вероятно, не нужен по соображениям скорости и, вероятно, также не подходит по соображениям точности.
Еще одну вещь, которую я добавлю, это то, что даже если вы знаете, что ваше приложение поддерживает только английский язык, ему все равно может потребоваться работать с именами людей, которые часто могут содержать символы, используемые в других языках, для которых столь же важно правильно сортировать, Использование правил Unicode для всего помогает добавить уверенности в том, что очень умные люди Unicode очень усердно работали, чтобы заставить сортировку работать правильно.
Что значат части
Во-первых, ci
предназначен для сортировки и сравнения без учета регистра. Это означает, что он подходит для текстовых данных, и дело не имеет значения. Другими типами сопоставления являются cs
(чувствительный к регистру) для текстовых данных, где важен регистр, и bin
, где кодирование должно совпадать, бит за битом, что подходит для полей, которые действительно кодируются двоичными данными (включая, например, Base64). Сортировка с учетом регистра приводит к некоторым странным результатам, а сравнение с учетом регистра может привести к тому, что повторяющиеся значения, отличающиеся только регистром букв, поэтому регистры с учетом регистра теряют предпочтение для текстовых данных - если регистр имеет значение для вас, то в противном случае игнорируемая пунктуация и так далее, вероятно, также важно, и двоичное сопоставление может быть более подходящим.
Далее, unicode
или general
относится к конкретным правилам сортировки и сравнения - в частности, к способу нормализации или сравнения текста. Существует множество различных наборов правил для кодировки символов utf8mb4, причем unicode
и general
являются двумя, которые пытаются хорошо работать на всех возможных языках, а не на одном конкретном. Различия между этими двумя наборами правил являются предметом этого ответа. Обратите внимание, что более новые наборы правил включают в себя 0900
со ссылкой на Unicode 9.0 и unicode_520
со ссылкой на Unicode 5.2.
И, наконец, utf8mb4
- это, конечно, внутренняя кодировка символов. В этом ответе я говорю только о Unicode-кодировках.