10.10.1 Наборы символов Unicode
В этом разделе описываются доступные для наборов символов Unicode правила сортировки и их отличительные свойства. Для общей информации о Unicode см. Раздел 10.9, «Поддержка Unicode».
MySQL поддерживает несколько наборов символов Unicode:
utf8mb4: Кодировка UTF-8 набора символов Unicode, использующая от одного до четырёх байтов на символ.utf8mb3: Кодировка UTF-8 набора символов Unicode, использующая от одного до трёх байтов на символ.utf8: Псевдоним дляutf8mb3.ucs2: Кодировка UCS-2 набора символов Unicode, использующая два байта на символ.utf16: Кодировка UTF-16 для набора символов Unicode, использующая два или четыре байта на символ. Подобноucs2, но с расширением для дополнительных символов.utf16le: Кодировка UTF-16LE для набора символов Unicode. Подобноutf16, но с порядком байтов little-endian вместо big-endian.utf32: Кодировка UTF-32 для набора символов Unicode, использующая четыре байта на символ.
utf8mb4, utf16, utf16le и utf32 поддерживают символы базовой многоязычной плоскости (BMP) и дополнительные символы, которые лежат за пределами BMP. utf8 и ucs2 поддерживают только символы BMP.
Большинство наборов символов Unicode имеют общее правило сортировки (указанное как _general в имени или отсутствием спецификатора языка), двоичное правило сортировки (указанное как _bin в имени) и несколько правил сортировки, специфичных для языка (указанные спецификаторами языка). Например, для utf8mb4, utf8mb4_general_ci и utf8mb4_bin являются общими и двоичными правилами сортировки, а utf8mb4_danish_ci — одним из правил сортировки, специфичных для языка.
Поддержка правил сортировки для utf16le ограничена. Доступны только правила сортировки utf16le_general_ci и utf16le_bin. Они аналогичны utf16_general_ci и utf16_bin.
Версии алгоритма сортировки Unicode (UCA)
MySQL реализует правила сортировки в соответствии с алгоритмом сортировки Unicode (UCA), описанным на http://www.unicode.org/reports/tr10/. Правило сортировки использует ключи весов UCA версии 4.0.0: http://www.unicode.org/Public/UCA/4.0.0/allkeys-4.0.0.txt. Правила сортировки xxx_unicode_ci имеют только частичную поддержку алгоритма сортировки Unicode. Некоторые символы не поддерживаются, и знаки объединения не поддерживаются полностью. Это в первую очередь затрагивает вьетнамский, йоруба и некоторые другие языки, такие как навахо. Объединённый символ считается отличным от того же символа, написанного одним символом Unicode в строковых сравнениях, и эти два символа считаются имеющими разную длину (например, как возвращает функция xxx_unicode_ciCHAR_LENGTH() или в метаданных набора результатов).
Правила сортировки Unicode, основанные на версиях UCA, более высоких, чем 4.0.0, включают версию в имени правила сортировки. Таким образом, utf8_unicode_520_ci основан на ключах весов UCA 5.2.0 (http://www.unicode.org/Public/UCA/5.2.0/allkeys.txt).
Функции LOWER() и UPPER() выполняют сгибание регистра в соответствии с правилом сортировки их аргумента. Символ, у которого есть прописные и строчные варианты только в версии Unicode выше 4.0.0, преобразуется этими функциями только в том случае, если правило сортировки аргумента использует достаточно высокую версию UCA.
Правила сортировки, специфичные для языка
MySQL реализует правила сортировки Unicode, специфичные для языка, если порядок, основанный только на алгоритме сортировки Unicode (UCA), не подходит для языка. Правила сортировки, специфичные для языка, основаны на UCA с дополнительными правилами адаптации к языку. Примеры таких правил приведены далее в этом разделе. По вопросам конкретного порядка сортировки языка, http://unicode.org предоставляет диаграммы сортировки репозитория общих данных местной локализации (CLDR) по адресу http://www.unicode.org/cldr/charts/30/collation/index.html.
Имя языка, показанное в следующей таблице, указывает правило сортировки, специфичное для языка. Наборы символов Unicode могут включать правила сортировки для одного или нескольких из этих языков.
Таблица 10.3 Спецификаторы языка для правил сортировки набора символов Unicode
| Язык | Спецификатор языка |
|---|---|
| Классический латинский | roman |
| Хорватский | croatian |
| Чешский | czech |
| Датский | danish |
| Эсперанто | esperanto |
| Эстонский | estonian |
| Немецкий порядок телефонного справочника | german2 |
| Венгерский | hungarian |
| Исландский | icelandic |
| Латвийский | latvian |
| Литовский | lithuanian |
| Персидский | persian |
| Польский | polish |
| Румынский | romanian |
| Сингальский | sinhala |
| Словацкий | slovak |
| Словенский | slovenian |
| Современный испанский | spanish |
| Традиционный испанский | spanish2 |
| Шведский | swedish |
| Турецкий | turkish |
| Вьетнамский | vietnamese |
Хорватские правила сортировки настроены для следующих хорватских букв: Č, Ć, Dž, Đ, Lj, Nj, Š, Ž.
Датские правила сортировки также могут использоваться для норвежского языка.
Для правил сортировки классического латинского языка I и J сравниваются как равные, а U и V сравниваются как равные.
Доступны правила сортировки для современного и традиционного испанского языка. Для обоих, ñ (ñ) — отдельный символ между n и o. Кроме того, для традиционного испанского языка ch — отдельный символ между c и d, а ll — отдельный символ между l и m.
Традиционные испанские правила сортировки также могут использоваться для астурийского и галисийского языков.
Шведские правила сортировки включают шведские правила. Например, в шведском языке существует следующее соотношение, что не ожидается от носителей немецкого или французского языка:
Ü = Y < Ö
Сравнения _general_ci и _unicode_ci
Для любого набора символов Юникод операции, выполняемые с помощью набора сравнения , выполняются быстрее, чем с помощью набора сравнения xxx_general_ci. Например, сравнения с набором сравнения xxx_unicode_ciutf8_general_ci выполняются быстрее, но немного менее точно, чем сравнения с набором сравнения utf8_unicode_ci. Причина в том, что utf8_unicode_ci поддерживает сопоставления, такие как расширения; то есть, когда один символ сравнивается как равный сочетаниям других символов. Например, ß равен ss в немецком и некоторых других языках. utf8_unicode_ci также поддерживает сокращения и игнорируемые символы. utf8_general_ci — это набор сравнения по умолчанию, который не поддерживает расширения, сокращения или игнорируемые символы. Он может выполнять только однозначные сравнения между символами.
Для дополнительной иллюстрации следующие равенства выполняются как в utf8_general_ci, так и в utf8_unicode_ci (для эффекта этого в сравнениях или поисках см. Раздел 10.8.6, «Примеры эффекта набора сравнения»):
Ä = A
Ö = O
Ü = U
Различие между наборами сравнения заключается в том, что это верно для utf8_general_ci:
ß = s
В то время как это верно для utf8_unicode_ci, который поддерживает немецкий порядок DIN-1 (также известный как порядок словаря):
ß = ss
MySQL реализует наборы сравнения, специфичные для языка utf8, если порядок с использованием utf8_unicode_ci не подходит для языка. Например, utf8_unicode_ci прекрасно работает для немецкого словаря и французского, поэтому нет необходимости создавать специальные наборы сравнения utf8.
utf8_general_ci также подходит для немецкого и французского языков, за исключением того, что ß равен s, а не ss. Если это приемлемо для вашего приложения, вы должны использовать utf8_general_ci, потому что оно быстрее. Если это неприемлемо (например, если вам нужен немецкий порядок словаря), используйте utf8_unicode_ci, потому что оно более точное.
Если вам нужен немецкий порядок DIN-2 (справочник), используйте набор сравнения utf8_german2_ci, который сравнивает следующие наборы символов как равные:
Ä = Æ = AE
Ö = Œ = OE
Ü = UE
ß = ss
utf8_german2_ci аналогичен latin1_german2_ci, но последний не сравнивает Æ как равный AE или Œ как равный OE. Нет utf8_german_ci, соответствующего latin1_german_ci для немецкого порядка словаря, поскольку utf8_general_ci достаточен.
Вес сортировки символов
Вес сортировки символа определяется следующим образом:
Для всех наборов сравнения Юникод, кроме наборов сравнения
_bin(двоичного), MySQL выполняет поиск в таблице, чтобы найти вес сортировки символа.Для наборов сравнения
_binвес основан на кодовом значении, возможно, с добавленными ведущими нулевыми байтами.
Вес сортировки можно отобразить с помощью функции WEIGHT_STRING(). (См. Раздел 12.8, «Функции и операторы строк».) Если набор сравнения использует таблицу поиска весов, но символ отсутствует в таблице (например, потому что это “новый” символ), определение веса сортировки становится более сложным:
Для символов BMP в общих наборах сравнения (
) вес — это кодовое значение.xxx_general_ci-
Для символов BMP в наборах сравнения UCA (например,
и наборы сравнения, специфичные для языка), применяется следующий алгоритм:xxx_unicode_ciif (code >= 0x3400 && code <= 0x4DB5) base= 0xFB80; /* CJK Ideograph Extension */ else if (code >= 0x4E00 && code <= 0x9FA5) base= 0xFB40; /* CJK Ideograph */ else base= 0xFBC0; /* All other characters */ aaaa= base + (code >> 15); bbbb= (code & 0x7FFF) | 0x8000;
Результат — последовательность из двух элементов сортировки,
aaaa, за которым следуетbbbb. Например:mysql>
SELECT HEX(WEIGHT_STRING(_ucs2 0x04CF COLLATE ucs2_unicode_ci));+----------------------------------------------------------+ | HEX(WEIGHT_STRING(_ucs2 0x04CF COLLATE ucs2_unicode_ci)) | +----------------------------------------------------------+ | FBC084CF | +----------------------------------------------------------+Таким образом,
U+04cf CYRILLIC SMALL LETTER PALOCHKA, со всеми наборами сравнения UCA 4.0.0, больше, чемU+04c0 CYRILLIC LETTER PALOCHKA. С наборами сравнения UCA 5.2.0 все палочки сортируются вместе. -
Для дополнительных символов в общих наборах сравнения вес — это вес для
0xfffd REPLACEMENT CHARACTER. Для дополнительных символов в наборах сравнения UCA 4.0.0 их вес сортировки —0xfffd. То есть для MySQL все дополнительные символы равны друг другу и больше почти всех символов BMP.Пример с символами Дезерета и
COUNT(DISTINCT):CREATE TABLE t (s1 VARCHAR(5) CHARACTER SET utf32 COLLATE utf32_unicode_ci); INSERT INTO t VALUES (0xfffd); /* REPLACEMENT CHARACTER */ INSERT INTO t VALUES (0x010412); /* DESERET CAPITAL LETTER BEE */ INSERT INTO t VALUES (0x010413); /* DESERET CAPITAL LETTER TEE */ SELECT COUNT(DISTINCT s1) FROM t;
Результат равен 2, потому что в наборах сравнения MySQL
символ замены имеет весxxx_unicode_ci0x0dc6, в то время как Deseret Bee и Deseret Tee имеют вес0xfffd. (Если бы вместо этого использовался набор сравненияutf32_general_ci, результат был бы 1, потому что все три символа имеют вес0xfffdв этом наборе сравнения).Пример с клинописными символами и
WEIGHT_STRING():/* The four characters in the INSERT string are 00000041 # LATIN CAPITAL LETTER A 0001218F # CUNEIFORM SIGN KAB 000121A7 # CUNEIFORM SIGN KISH 00000042 # LATIN CAPITAL LETTER B */ CREATE TABLE t (s1 CHAR(4) CHARACTER SET utf32 COLLATE utf32_unicode_ci); INSERT INTO t VALUES (0x000000410001218f000121a700000042); SELECT HEX(WEIGHT_STRING(s1)) FROM t;
Результат:
0E33 FFFD FFFD 0E4A
0E33и0E4A— это первичные веса, как в UCA 4.0.0.FFFD— это вес для KAB и также для KISH.Правило, что все дополнительные символы равны друг другу, не является оптимальным, но, как ожидается, не вызовет проблем. Эти символы встречаются очень редко, поэтому крайне редко возникает ситуация, когда строка состоит целиком из дополнительных символов. В Японии, поскольку дополнительные символы являются малоизвестными иероглифами Кандзи, типичный пользователь не обращает внимания на их порядок. Если вам действительно нужно отсортировать строки по правилу MySQL и, во-вторых, по кодовому значению, это легко:
ORDER BY s1 COLLATE utf32_unicode_ci, s1 COLLATE utf32_bin
-
Для дополнительных символов, основанных на версиях UCA выше 4.0.0 (например,
), дополнительные символы не обязательно имеют одинаковый вес сортировки. У некоторых есть явные веса из файла UCAxxx_unicode_520_ciallkeys.txt. У других веса вычисляются по этому алгоритму:aaaa= base + (code >> 15); bbbb= (code & 0x7FFF) | 0x8000;
Существует разница между “сортировкой по кодовому значению символа” и “сортировкой по двоичному представлению символа”, разница, которая появляется только с utf16_bin из-за суррогатов.
Предположим, что utf16_bin (двоичный набор сравнения для utf16) был двоичным сравнением “байт за байтом”, а не “символ за символом”. Если бы это было так, порядок символов в utf16_bin отличался бы от порядка в utf8_bin. Например, следующая таблица показывает два редких символа. Первый символ находится в диапазоне E000-FFFF, поэтому он больше суррогата, но меньше дополнительного. Второй символ — дополнительный.
Code point Character utf8 utf16
---------- --------- ---- -----
0FF9D HALFWIDTH KATAKANA LETTER N EF BE 9D FF 9D
10384 UGARITIC LETTER DELTA F0 90 8E 84 D8 00 DF 84
Два символа в таблице расположены в порядке по кодовому значению, потому что 0xff9d < 0x10384. И они расположены в порядке по значению utf8, потому что 0xef < 0xf0. Но они не расположены в порядке по значению utf16, если мы используем сравнение байт за байтом, потому что 0xff > 0xd8.
Таким образом, набор сравнения MySQL utf16_bin не “побайтовый”. Это “по кодовому значению”. Когда MySQL видит кодировку дополнительного символа в utf16, он преобразует её в кодовое значение символа и затем сравнивает. Следовательно, utf8_bin и utf16_bin имеют одинаковый порядок. Это соответствует требованию стандарта SQL:2008 для набора сравнения UCS_BASIC: “UCS_BASIC — это набор сравнения, в котором порядок определяется исключительно числовыми значениями Unicode символов в сортируемых строках. Он применим к набору символов UCS. Поскольку каждый набор символов является подмножеством набора символов UCS, набор сравнения UCS_BASIC потенциально применим к каждому набору символов. ПРИМЕЧАНИЕ 11: Числовое значение Unicode символа — это его кодовое значение, рассматриваемое как целое без знака.”
Если набор символов — ucs2, сравнение выполняется побайтово, но строки ucs2 всё же не должны содержать суррогатов.
Разное
Наборы сравнения сохраняют порядок наборов сравнения xxx_general_mysql500_ci до версии 5.1.24 и позволяют выполнить обновление для таблиц, созданных до MySQL 5.1.24 (Ошибка #27877). xxx_general_ci
© 2025 Oracle
Licensed under the GPLv2 License.