За тези хора, които все още стигат до този въпрос през 2020 г. или по-късно, има по-нови опции, които може да са по-добри от и двете от тях. Например, utf8mb4_0900_ai_ci
.
Всички тези съпоставяния са за кодирането на знаци UTF-8. Разликите са в това как текстът се сортира и сравнява.
_unicode_ci
и _general_ci
са два различни набора от правила за сортиране и сравняване на текст според начина, по който очакваме. По-новите версии на MySQL въвеждат и нови набори от правила, като _0900_ai_ci
за еквивалентни правила, базирани на Unicode 9.0 - и без еквивалент _general_ci
вариант. Хората, които четат това сега, вероятно трябва да използват едно от тези по-нови съпоставяния вместо _unicode_ci
или _general_ci
. Описанието на тези по-стари съпоставки по-долу е предоставено само за интерес.
MySQL в момента преминава от по-стара, дефектна реализация на UTF-8. Засега трябва да използвате utf8mb4
вместо utf8
за частта за кодиране на знаци, за да сте сигурни, че получавате фиксираната версия. Погрешната версия остава за обратна съвместимост, въпреки че е оттеглена.
Основни разлики
-
utf8mb4_unicode_ci
се основава на официалните правила на Unicode за универсално сортиране и сравнение, което сортира точно в широк спектър от езици. -
utf8mb4_general_ci
е опростен набор от правила за сортиране, който има за цел да направи възможно най-добре, като същевременно използва много преки пътища, предназначени да подобрят скоростта. Той не следва правилата на Unicode и ще доведе до нежелано сортиране или сравнение в някои ситуации, като например при използване на определени езици или знаци.На съвременните сървъри това повишаване на производителността ще бъде почти незначително. Той е създаден във времена, когато сървърите са имали малка част от производителността на процесора в сравнение с днешните компютри.
Предимства на utf8mb4_unicode_ci
през utf8mb4_general_ci
utf8mb4_unicode_ci
, който използва правилата на Unicode за сортиране и сравнение, използва доста сложен алгоритъм за правилно сортиране в широк диапазон от езици и при използване на широк набор от специални знаци. Тези правила трябва да вземат предвид специфичните за езика конвенции; не всеки сортира знаците си в това, което бихме нарекли „азбучен ред“.
Що се отнася до латинските (т.е. „европейските“) езици, няма голяма разлика между сортирането на Unicode и опростеното utf8mb4_general_ci
сортиране в MySQL, но все още има няколко разлики:
-
Например, съпоставянето на Unicode сортира "ß" като "ss" и "Œ" като "OE", както хората, използващи тези знаци, обикновено биха искали, докато
utf8mb4_general_ci
сортира ги като единични знаци (вероятно като "s" и "e" съответно). -
Някои символи в Unicode са дефинирани като игнорирани, което означава, че не трябва да се отчитат в реда на сортиране и вместо това сравнението трябва да премине към следващия знак.
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
са два, които се опитват да работят добре на всички възможни езици, а не на един конкретен. Разликите между тези два набора от правила са предмет на този отговор. Имайте предвид, че unicode
използва правила от Unicode 4.0. Последните версии на MySQL добавят наборите от правила unicode_520
използвайки правила от Unicode 5.2 и 0900
(изпускане на частта "unicode_") с помощта на правила от Unicode 9.0.
И накрая, utf8mb4
е разбира се кодирането на знаци, използвано вътрешно. В този отговор говоря само за кодировки, базирани на Unicode.