Spec-Zone.ru › MySQL 5.7

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)

  • Правила сортировки, специфичные для языка

  • Правила сортировки _general_ci против _unicode_ci

  • Веса сортировки символов

  • Разное

Версии алгоритма сортировки Unicode (UCA)

MySQL реализует правила сортировки xxx_unicode_ci в соответствии с алгоритмом сортировки 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 в строковых сравнениях, и эти два символа считаются имеющими разную длину (например, как возвращает функция CHAR_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

Таблица 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_ci. Например, сравнения с набором сравнения utf8_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_ci и наборы сравнения, специфичные для языка), применяется следующий алгоритм:

    if (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_ci символ замены имеет вес 0x0dc6, в то время как 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 (например, xxx_unicode_520_ci), дополнительные символы не обязательно имеют одинаковый вес сортировки. У некоторых есть явные веса из файла UCA allkeys.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 сохраняют порядок наборов сравнения xxx_general_ci до версии 5.1.24 и позволяют выполнить обновление для таблиц, созданных до MySQL 5.1.24 (Ошибка #27877).

© 2025 Oracle
Licensed under the GPLv2 License.
https://docs.oracle.com/cd/E17952_01/mysql-5.7-en/charset-unicode-sets.html

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API