Если вам нравится utf8[mb4]_unicode_ci, вам может понравиться utf8[mb4]_unicode_520_ciеще больше.
Рик Джеймс
8
Я не знаю, что я чувствую по этому поводу - вместо того, чтобы привести их реализацию в соответствие с последним стандартом Unicode, они оставляют устаревшую версию по умолчанию, и люди должны добавить «520», чтобы использовать правильную версию сейчас. И он не поддерживает прямую и обратную совместимость, потому что вы не можете использовать версию «520» в старых версиях MySQL. Почему они не могли просто обновить существующие параметры сортировки? То же самое с "mb4", правда. Какой код действительно зависит от старого, ограниченного / устаревшего поведения, чтобы оправдать его сохранение по умолчанию?
Томасруттер
7
Еще лучше, 8.0 по умолчанию utf8mb4_0900_ai_ci.
Рик Джеймс
Ответы:
1591
Эти два сопоставления предназначены для кодировки символов UTF-8. Различия в том, как текст сортируется и сравнивается.
Примечание: в MySQL вы должны использовать, utf8mb4а не utf8. Это сбивает с толку utf8ошибочную реализацию UTF-8 из ранних версий MySQL, которая остается только для обратной совместимости. Фиксированной версии дали имя utf8mb4.
Примечание. В новых версиях MySQL обновлены правила сортировки Unicode, доступные под именами, например, utf8mb4_0900_ai_ciдля эквивалентных правил, основанных на Unicode 9.0, и без эквивалентного _generalварианта. Люди, читающие это сейчас, вероятно, должны использовать одно из этих новых сопоставлений вместо либо, _unicodeлибо_general . Многое из того, что написано ниже, больше не представляет большого интереса, если вместо этого вы можете использовать один из более новых сопоставлений.
Ключевые отличия
utf8mb4_unicode_ci основан на официальных правилах Unicode для универсальной сортировки и сравнения, которая точно сортирует по широкому спектру языков.
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быть два , которые пытаются хорошо работать во всех возможных языках , а не один конкретный один. Различия между этими двумя наборами правил являются предметом этого ответа. Обратите внимание, что unicodeиспользуются правила из Unicode 4.0. Последние версии MySQL добавляют наборы правил, unicode_520используя правила из Unicode 5.2, и 0900(отбрасывая часть "unicode_"), используя правила из Unicode 9.0.
И, наконец, utf8mb4конечно же, внутренняя кодировка символов. В этом ответе я говорю только о Unicode-кодировках.
@KahWeeTeng Вы никогда не должны, никогда не используйте utf8_general_ci: это просто не работает. Это возвращение к плохим старым временам ASCII-ступенек с пятидесятилетней давности. Сопоставление без учета регистра в Юникоде невозможно без карты сгиба из UCD. Например, «Σίσυφος» содержит три разных сигмы; или как строчная буква «TSCHüẞ» - «tschüβ», а прописная буква «tschüβ» - «TSCHÜSS». Вы можете быть правы, или вы можете быть быстрым. Поэтому вы должны использовать utf8_unicode_ci, потому что, если вы не заботитесь о правильности, то тривиально сделать это бесконечно быстро.
tchrist
7
Прочитав это, я также обнаружил, что utf8_unicode_ci будет считать любые символы с одинаковым весом сопоставления равными для сравнения на равенство. Это приводит к случаям, когда "か" == "が"или "ǽ" == "æ". Для сортировки это имеет смысл, но может быть удивительно, когда вы выбираете с помощью равенств или имеете дело с уникальными индексами - bugs.mysql.com/bug.php?id=16526
Мэт Шаффер,
4
@DanHorvat Единственная практическая причина ограничиться более старым, более ограниченным подмножеством Unicode в MySQL - это если у вас есть старая версия MySQL, которая не поддерживает более полную utf8mb4. 5.5.3 старше 5 лет. Я понимаю , что Plesk работает по другому расписанию MySQL, но большинство дистрибутивов на MySQL 5.5 сейчас и Plesk 11.x делает поддержку MySQL 5.5 , если ее компоненты.
Томасруттер
22
Я бы не согласился с тем, что использование более нового, более стандартного варианта жалоб является плохой практикой, и я думаю, что подстрекать людей к плохим разработчикам подстрекать к чему-то вроде этого. Вы также можете заметить, что мой ответ в его нынешнем виде гласит: « В новых версиях MySQL используйте utf8mb4, а не utf8», акцент мой.
Томасруттер
24
@DanHorvat utf8mb4- единственный правильный выбор . С utf8вы застряли в каком - то MySQL-только, 3-байтовый вариант UTF8 , что только MySQL (и MariaDB) знают , что делать с. Остальной мир использует UTF8, который может содержать до 4 байтов на символ . Разработчики MySQL неправильно назвали свою кодировку homebrew utf8и, чтобы не нарушать обратную совместимость, теперь они должны ссылаться на настоящий UTF8 как utf8mb4.
Стейн де Витт
162
Я хотел знать, в чем разница в производительности между использованием utf8_general_ciи utf8_unicode_ci, но я не нашел никаких тестов, перечисленных в Интернете, поэтому я решил создать тесты самостоятельно.
Я создал очень простую таблицу с 500 000 строк:
CREATETABLE test(
ID INT(11)DEFAULTNULL,
Description VARCHAR(20)DEFAULTNULL)
ENGINE = INNODB
CHARACTER SET utf8
COLLATE utf8_general_ci;
Затем я заполнил его случайными данными, запустив эту хранимую процедуру:
CREATEPROCEDURE randomizer()BEGINDECLARE i INT DEFAULT0;DECLARE random CHAR(20);
theloop: loop
SET random = CONV(FLOOR(RAND()*99999999999999),20,36);INSERTINTO test VALUES(i+1, random);SET i=i+1;IF i =500000THEN
LEAVE theloop;ENDIF;END LOOP theloop;END
Затем я создал следующие хранимые процедуры для сравнения простых SELECT, SELECTс LIKEи сортировки ( SELECTс ORDER BY):
CREATEPROCEDURE benchmark_simple_select()BEGINDECLARE i INT DEFAULT0;
theloop: loop
SELECT*FROM test
WHERE Description ='test'COLLATE utf8_general_ci;SET i = i +1;IF i =30THEN
LEAVE theloop;ENDIF;END LOOP theloop;END;CREATEPROCEDURE benchmark_select_like()BEGINDECLARE i INT DEFAULT0;
theloop: loop
SELECT*FROM test
WHERE Description LIKE'%test'COLLATE utf8_general_ci;SET i = i +1;IF i =30THEN
LEAVE theloop;ENDIF;END LOOP theloop;END;CREATEPROCEDURE benchmark_order_by()BEGINDECLARE i INT DEFAULT0;
theloop: loop
SELECT*FROM test
WHERE ID > FLOOR(1+ RAND()*(400000-1))ORDERBY Description COLLATE utf8_general_ci LIMIT 1000;SET i = i +1;IF i =10THEN
LEAVE theloop;ENDIF;END LOOP theloop;END;
В вышеупомянутых хранимых процедурах utf8_general_ciиспользуется сопоставление, но, конечно же, во время тестов я использовал и то, utf8_general_ciи другое utf8_unicode_ci.
Я вызывал каждую хранимую процедуру 5 раз для каждого сопоставления (5 раз для utf8_general_ciи 5 раз для utf8_unicode_ci), а затем вычислял средние значения.
Мои результаты:
benchmark_simple_select()
с utf8_general_ci: 9,957 мс
с utf8_unicode_ci: 10 271 мс
В этом тесте использование utf8_unicode_ciмедленнее, чем utf8_general_ciна 3,2%.
benchmark_select_like()
с utf8_general_ci: 11,441 мс
с utf8_unicode_ci: 12,811 мс
В этом тесте использование utf8_unicode_ciмедленнее, чем utf8_general_ciна 12%.
benchmark_order_by()
с utf8_general_ci: 11,944 мс
с utf8_unicode_ci: 12,887 мс
В этом тесте использование utf8_unicode_ciмедленнее, чем utf8_general_ciна 7,9%.
Хороший тест, спасибо, что поделились. Я получаю разумно похожие цифры (MySQL v5.6.12 для Windows): 10%, 4%, 8%. Я согласен: прирост производительности utf8_general_ciслишком минимален, чтобы его стоило использовать.
RandomSeed
10
1) Но не должен ли этот эталонный тест произвести аналогичные результаты для двух сопоставлений по определению? Я имею в виду CONV(FLOOR(RAND() * 99999999999999), 20, 36)генерирует только ASCII, и никаких символов Unicode для обработки алгоритмами сопоставления. 2) Description = 'test' COLLATE ...и Description LIKE 'test%' COLLATE ...обрабатывают только одну строку («тест») во время выполнения, не так ли? 3) В реальных приложениях столбцы, используемые при упорядочении, вероятно, будут проиндексированы, и скорость индексации для разных сопоставлений с реальным текстом, не относящимся к ASCII, может отличаться.
Халил Озгюр
2
@ HalilÖzgür - вы ошибаетесь. Я предполагаю, что дело не в значении кодовой точки вне ASCII (которое general_ci будет обрабатывать правильно), а в специфических особенностях, таких как обработка умлаутов, написанных как "Uml ea ute" или некоторых подобных тонкостей.
Вкратце: utf8_unicode_ci использует алгоритм сопоставления Unicode, как определено в стандартах Unicode, тогда как utf8_general_ci - более простой порядок сортировки, который приводит к «менее точным» результатам сортировки.
Спасибо. это было мое впечатление. я возьму хит производительности :)
onassar
7
Если вас не заботит правильность, то сделать любой алгоритм бесконечно быстрым. Просто используйте utf8_unicode_ciи сделайте вид, что другого не существует.
tchrist
1
@tchrist, но если вы заботитесь об определенном балансе между правильностью и скоростью, это utf8_general_ciможет быть для вас
Shelvacu
@tchrist Никогда не становись программистом игры;)
Stijn de Witt
1
@onassar - MySQL 8.0 утверждает, что значительно улучшил производительность всех параметров сортировки.
Для любого набора символов Unicode операции, выполняемые с использованием параметров сортировки _general_ci, выполняются быстрее, чем операции с параметрами сортировки _unicode_ci. Например, сравнения для сопоставления utf8_general_ci выполняются быстрее, но немного менее корректно, чем сравнения для utf8_unicode_ci. Причина этого в том, что utf8_unicode_ci поддерживает такие отображения, как расширения; то есть, когда один символ сравнивается как равный комбинации других символов. Например, в немецком и некоторых других языках «ß» равно «ss». utf8_unicode_ci также поддерживает сокращения и игнорируемые символы. utf8_general_ci - это устаревшая сортировка, которая не поддерживает расширения, сокращения или игнорируемые символы. Он может делать только однозначное сравнение между персонажами.
Подводя итог, можно сказать, что utf_general_ci использует меньший и менее правильный (согласно стандарту) набор сравнений, чем utf_unicode_ci, который должен реализовывать весь стандарт. Набор general_ci будет быстрее, потому что требуется меньше вычислений.
Нет такой вещи, как «чуть менее правильно». Корректность является булевой характеристикой; он не допускает модификаторов степени. Просто используйте utf8_unicode_ciи сделайте вид, что неисправной версии не существует.
tchrist
2
У меня были проблемы с получением 5.6.15 для установки collation_connection, и оказалось, что вы должны передать его в строке SET, например «SET NAMES utf8mb4 COLLATE utf8mb4_unicode_ci». Автор благодарен Матиасу Биненсу за решение, вот его очень полезное руководство: mathiasbynens.be/notes/mysql-utf8mb4
Стив Хибберт,
4
@tchrist Проблема с правильностью состоит в том, что булевость состоит в том, что она не учитывает ситуации, которые не основаны на абсолютной корректности. Ваш базовый пункт не является недействительным, и я не пытаюсь поддержать преимущества general_ci, но ваше общее утверждение о правильности легко опровергается. Я делаю это ежедневно в своей профессии. Комедия в стороне, Стюарт имеет хорошую точку здесь .
Энтони
5
С геолокацией или разработкой игр мы постоянно торгуем корректностью и производительностью. И, конечно, правильность - это действительное число между, 0а 1не бул. :) Например, выбор географических точек в ограничительной рамке - это аппроксимация «соседних точек», которая не так хороша, как вычисление расстояния между точкой и контрольной точкой и фильтрация по ней. Но оба они являются приблизительными, и на самом деле, полная корректность в большинстве случаев недостижима. См. Парадокс береговой линии и IEEE 754
Стейн де Витт
4
TL; DR : Пожалуйста, предоставьте программу, которая печатает правильный результат для1/3
Stijn de Witt
7
Вкратце:
Если вам нужен лучший порядок сортировки - используйте utf8_unicode_ci(это предпочтительный метод),
но если вы крайне заинтересованы в производительности - используйте utf8_general_ci, но знайте, что она немного устарела.
Различия с точки зрения производительности очень незначительны.
Оба устарели сейчас - см. Принятый ответ для более
thomasrutter
Хорошо, спасибо @thomasrutter
simhumileco
6
Некоторые детали (PL)
Как мы можем прочитать здесь ( Питер Гулутзан ), есть разница в сортировке / сравнении польской буквы "Ł" (L с штрихом - html esc:) Ł(нижний регистр: "ł" - html esc:) ł- у нас есть следующее предположение:
utf8_polish_ci Ł greater than L and less than M
utf8_unicode_ci Ł greater than L and less than M
utf8_unicode_520_ci Ł equal to L
utf8_general_ci Ł greater than Z
На польском языке буква Łпосле буквы Lи до M. Ни одна из этих кодировок не является лучше или хуже - это зависит от ваших потребностей.
Есть две большие разницы: сортировка и сопоставление символов:
Сортировка :
utf8mb4_general_ci удаляет все акценты и сортирует их по одному, что может привести к неверным результатам сортировки.
utf8mb4_unicode_ci сортирует точно.
Подбор персонажей
Они соответствуют персонажам по-разному.
Например, у utf8mb4_unicode_ciвас есть i != ı, но в utf8mb4_general_ciнем держит ı=i.
Например, представьте, что у вас есть ряд с name="Yılmaz". затем
select id from users where name='Yilmaz';
возвратил бы строку, если есть словосочетание utf8mb4_general_ci, но если оно будет размещено вместе с utf8mb4_unicode_ciним, не вернет строку!
С другой стороны , мы имеем , что a=ªи ß=ssв utf8mb4_unicode_ciкоторых не бывает в utf8mb4_general_ci. Итак , представьте , у вас есть строка с name="ªßi", то
select id from users where name='assi';
вернет строку, если используется словосочетание utf8mb4_unicode_ci, но не вернет строку, если для словосочетания установлено значение utf8mb4_general_ci.
Полный список совпадений для каждого словосочетания можно найти здесь .
utf8[mb4]_unicode_ci
, вам может понравитьсяutf8[mb4]_unicode_520_ci
еще больше.utf8mb4_0900_ai_ci
.Ответы:
Эти два сопоставления предназначены для кодировки символов UTF-8. Различия в том, как текст сортируется и сравнивается.
Примечание: в MySQL вы должны использовать,
utf8mb4
а неutf8
. Это сбивает с толкуutf8
ошибочную реализацию UTF-8 из ранних версий MySQL, которая остается только для обратной совместимости. Фиксированной версии дали имяutf8mb4
.Примечание. В новых версиях MySQL обновлены правила сортировки Unicode, доступные под именами, например,
utf8mb4_0900_ai_ci
для эквивалентных правил, основанных на Unicode 9.0, и без эквивалентного_general
варианта. Люди, читающие это сейчас, вероятно, должны использовать одно из этих новых сопоставлений вместо либо,_unicode
либо_general
. Многое из того, что написано ниже, больше не представляет большого интереса, если вместо этого вы можете использовать один из более новых сопоставлений.Ключевые отличия
utf8mb4_unicode_ci
основан на официальных правилах Unicode для универсальной сортировки и сравнения, которая точно сортирует по широкому спектру языков.utf8mb4_general_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
быть два , которые пытаются хорошо работать во всех возможных языках , а не один конкретный один. Различия между этими двумя наборами правил являются предметом этого ответа. Обратите внимание, чтоunicode
используются правила из Unicode 4.0. Последние версии MySQL добавляют наборы правил,unicode_520
используя правила из Unicode 5.2, и0900
(отбрасывая часть "unicode_"), используя правила из Unicode 9.0.И, наконец,
utf8mb4
конечно же, внутренняя кодировка символов. В этом ответе я говорю только о Unicode-кодировках.источник
utf8_general_ci
: это просто не работает. Это возвращение к плохим старым временам ASCII-ступенек с пятидесятилетней давности. Сопоставление без учета регистра в Юникоде невозможно без карты сгиба из UCD. Например, «Σίσυφος» содержит три разных сигмы; или как строчная буква «TSCHüẞ» - «tschüβ», а прописная буква «tschüβ» - «TSCHÜSS». Вы можете быть правы, или вы можете быть быстрым. Поэтому вы должны использоватьutf8_unicode_ci
, потому что, если вы не заботитесь о правильности, то тривиально сделать это бесконечно быстро."か" == "が"
или"ǽ" == "æ"
. Для сортировки это имеет смысл, но может быть удивительно, когда вы выбираете с помощью равенств или имеете дело с уникальными индексами - bugs.mysql.com/bug.php?id=16526utf8mb4
- единственный правильный выбор . Сutf8
вы застряли в каком - то MySQL-только, 3-байтовый вариант UTF8 , что только MySQL (и MariaDB) знают , что делать с. Остальной мир использует UTF8, который может содержать до 4 байтов на символ . Разработчики MySQL неправильно назвали свою кодировку homebrewutf8
и, чтобы не нарушать обратную совместимость, теперь они должны ссылаться на настоящий UTF8 какutf8mb4
.Я хотел знать, в чем разница в производительности между использованием
utf8_general_ci
иutf8_unicode_ci
, но я не нашел никаких тестов, перечисленных в Интернете, поэтому я решил создать тесты самостоятельно.Я создал очень простую таблицу с 500 000 строк:
Затем я заполнил его случайными данными, запустив эту хранимую процедуру:
Затем я создал следующие хранимые процедуры для сравнения простых
SELECT
,SELECT
сLIKE
и сортировки (SELECT
сORDER BY
):В вышеупомянутых хранимых процедурах
utf8_general_ci
используется сопоставление, но, конечно же, во время тестов я использовал и то,utf8_general_ci
и другоеutf8_unicode_ci
.Я вызывал каждую хранимую процедуру 5 раз для каждого сопоставления (5 раз для
utf8_general_ci
и 5 раз дляutf8_unicode_ci
), а затем вычислял средние значения.Мои результаты:
benchmark_simple_select()
utf8_general_ci
: 9,957 мсutf8_unicode_ci
: 10 271 мсВ этом тесте использование
utf8_unicode_ci
медленнее, чемutf8_general_ci
на 3,2%.benchmark_select_like()
utf8_general_ci
: 11,441 мсutf8_unicode_ci
: 12,811 мсВ этом тесте использование
utf8_unicode_ci
медленнее, чемutf8_general_ci
на 12%.benchmark_order_by()
utf8_general_ci
: 11,944 мсutf8_unicode_ci
: 12,887 мсВ этом тесте использование
utf8_unicode_ci
медленнее, чемutf8_general_ci
на 7,9%.источник
utf8_general_ci
слишком минимален, чтобы его стоило использовать.CONV(FLOOR(RAND() * 99999999999999), 20, 36)
генерирует только ASCII, и никаких символов Unicode для обработки алгоритмами сопоставления. 2)Description = 'test' COLLATE ...
иDescription LIKE 'test%' COLLATE ...
обрабатывают только одну строку («тест») во время выполнения, не так ли? 3) В реальных приложениях столбцы, используемые при упорядочении, вероятно, будут проиндексированы, и скорость индексации для разных сопоставлений с реальным текстом, не относящимся к ASCII, может отличаться.Этот пост описывает это очень хорошо.
Вкратце: utf8_unicode_ci использует алгоритм сопоставления Unicode, как определено в стандартах Unicode, тогда как utf8_general_ci - более простой порядок сортировки, который приводит к «менее точным» результатам сортировки.
источник
utf8_unicode_ci
и сделайте вид, что другого не существует.utf8_general_ci
может быть для васСм. Руководство по mysql, раздел « Наборы символов Unicode »:
Подводя итог, можно сказать, что utf_general_ci использует меньший и менее правильный (согласно стандарту) набор сравнений, чем utf_unicode_ci, который должен реализовывать весь стандарт. Набор general_ci будет быстрее, потому что требуется меньше вычислений.
источник
utf8_unicode_ci
и сделайте вид, что неисправной версии не существует.0
а1
не бул. :) Например, выбор географических точек в ограничительной рамке - это аппроксимация «соседних точек», которая не так хороша, как вычисление расстояния между точкой и контрольной точкой и фильтрация по ней. Но оба они являются приблизительными, и на самом деле, полная корректность в большинстве случаев недостижима. См. Парадокс береговой линии и IEEE 7541/3
Вкратце:
Если вам нужен лучший порядок сортировки - используйте
utf8_unicode_ci
(это предпочтительный метод),но если вы крайне заинтересованы в производительности - используйте
utf8_general_ci
, но знайте, что она немного устарела.Различия с точки зрения производительности очень незначительны.
источник
Некоторые детали (PL)
Как мы можем прочитать здесь ( Питер Гулутзан ), есть разница в сортировке / сравнении польской буквы "Ł" (L с штрихом - html esc:)
Ł
(нижний регистр: "ł" - html esc:)ł
- у нас есть следующее предположение:На польском языке буква
Ł
после буквыL
и доM
. Ни одна из этих кодировок не является лучше или хуже - это зависит от ваших потребностей.источник
Есть две большие разницы: сортировка и сопоставление символов:
Сортировка :
utf8mb4_general_ci
удаляет все акценты и сортирует их по одному, что может привести к неверным результатам сортировки.utf8mb4_unicode_ci
сортирует точно.Подбор персонажей
Они соответствуют персонажам по-разному.
Например, у
utf8mb4_unicode_ci
вас естьi != ı
, но вutf8mb4_general_ci
нем держитı=i
.Например, представьте, что у вас есть ряд с
name="Yılmaz"
. затемвозвратил бы строку, если есть словосочетание
utf8mb4_general_ci
, но если оно будет размещено вместе сutf8mb4_unicode_ci
ним, не вернет строку!С другой стороны , мы имеем , что
a=ª
иß=ss
вutf8mb4_unicode_ci
которых не бывает вutf8mb4_general_ci
. Итак , представьте , у вас есть строка сname="ªßi"
, товернет строку, если используется словосочетание
utf8mb4_unicode_ci
, но не вернет строку, если для словосочетания установлено значениеutf8mb4_general_ci
.Полный список совпадений для каждого словосочетания можно найти здесь .
источник
Согласно этому сообщению, MySQL 5.7 значительно повышает производительность при использовании utf8mb4_general_ci вместо utf8mb4_unicode_ci: https://www.percona.com/blog/2019/02/27/charset-and-collation-settings-impact. -он-MySQL-производительность /
источник