Spec-Zone.ru › MySQL 8.4

12.10.1 Наборы символов Unicode

В этом разделе описаны доступные сортировки для наборов символов Unicode и их отличительные свойства. Для общей информации об Unicode см. раздел 12.9, «Поддержка Unicode».

MySQL поддерживает несколько наборов символов Unicode:

  • utf8mb4: Кодировка UTF-8 набора символов Unicode, использующая от одного до четырёх байтов на символ.

  • utf8mb3: Кодировка UTF-8 набора символов Unicode, использующая от одного до трёх байтов на символ. Этот набор символов устарел; используйте utf8mb4 вместо него.

  • utf8: Устаревший псевдоним для utf8mb3. Используйте utf8mb4 вместо него.

    Примечание

    utf8 ожидается в будущей версии стать псевдонимом для utf8mb4.

  • ucs2: Кодировка UCS-2 набора символов Unicode, использующая два байта на символ. Устарело; ожидается, что поддержка этого набора символов будет удалена в будущей версии MySQL.

  • utf16: Кодировка UTF-16 для набора символов Unicode, использующая два или четыре байта на символ. Как и ucs2, но с расширением для дополнительных символов.

  • utf16le: Кодировка UTF-16LE для набора символов Unicode. Как utf16, но с порядком байтов little-endian, а не big-endian.

  • utf32: Кодировка UTF-32 для набора символов Unicode, использующая четыре байта на символ.

Примечание

Набор символов utf8mb3 устарел и должен быть удалён в будущей версии MySQL. Используйте utf8mb4 вместо него. utf8 в настоящее время является псевдонимом для utf8mb3, но теперь он устарел, и utf8 ожидается, что впоследствии станет ссылкой на utf8mb4. utf8mb3 также отображается вместо utf8 в столбцах таблиц Information Schema и в выводе SQL-запросов SHOW.

Чтобы избежать неоднозначности в отношении значения utf8, укажите utf8mb4 явно для ссылок на наборы символов.

utf8mb4, utf16, utf16le и utf32 поддерживают символы базовой многоязычной плоскости (BMP) и дополнительные символы, которые находятся за пределами BMP. utf8mb3 и ucs2 поддерживают только символы BMP.

Большинство наборов символов Unicode имеют общую сортировку (указанную как _general в названии или в отсутствие спецификатора языка), двоичную сортировку (указанную как _bin в названии) и несколько сортировок, специфичных для языка (указанных спецификаторами языка). Например, для utf8mb4, utf8mb4_general_ci и utf8mb4_bin являются общими и двоичными сортировками, а utf8mb4_danish_ci — одной из сортировок, специфичных для языка.

Большинство наборов символов имеют одну двоичную сортировку. utf8mb4 является исключением, имеющим две: utf8mb4_bin и utf8mb4_0900_bin. Эти две двоичные сортировки имеют одинаковый порядок сортировки, но различаются атрибутом заполнения и характеристиками сопоставляющих весов. См. Атрибуты заполнения сортировки и Веса сопоставления символов.

Поддержка сортировки для utf16le ограничена. Доступны только сортировки utf16le_general_ci и utf16le_bin. Они аналогичны utf16_general_ci и utf16_bin.

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

  • Атрибуты заполнения сортировки

  • Языковые сортировки

  • Сортировки _general_ci Versus _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, включают версию в имени сортировки. Примеры:

  • utf8mb4_unicode_520_ci основана на ключах весов UCA 5.2.0 (http://www.unicode.org/Public/UCA/5.2.0/allkeys.txt),

  • utf8mb4_0900_ai_ci основана на ключах весов UCA 9.0.0 (http://www.unicode.org/Public/UCA/9.0.0/allkeys.txt).

Функции LOWER() и UPPER() выполняют сгибание регистра в соответствии с сортировкой их аргумента. Символ, имеющий прописные и строчные версии только в версии Unicode, более поздней чем 4.0.0, преобразуется этими функциями только в том случае, если сортировка аргумента использует достаточно высокую версию UCA.

Атрибуты заполнения сортировки

Сортировки, основанные на UCA 9.0.0 и более поздних версиях, быстрее, чем сортировки, основанные на версиях UCA, предшествующих 9.0.0. Они также имеют атрибут заполнения NO PAD, в отличие от PAD SPACE, используемого в сортировках, основанных на версиях UCA, предшествующих 9.0.0. Для сравнения строк, отличных от двоичных, сортировки NO PAD рассматривают пробелы в конце строк как любой другой символ (см. Обработка пробелов в конце при сравнении).

Чтобы определить атрибут заполнения для сортировки, используйте таблицу INFORMATION_SCHEMA COLLATIONS, которая имеет столбец PAD_ATTRIBUTE. Например:

mysql> SELECT COLLATION_NAME, PAD_ATTRIBUTE
       FROM INFORMATION_SCHEMA.COLLATIONS
       WHERE CHARACTER_SET_NAME = 'utf8mb4';
+----------------------------+---------------+
| COLLATION_NAME             | PAD_ATTRIBUTE |
+----------------------------+---------------+
| utf8mb4_general_ci         | PAD SPACE     |
| utf8mb4_bin                | PAD SPACE     |
| utf8mb4_unicode_ci         | PAD SPACE     |
| utf8mb4_icelandic_ci       | PAD SPACE     |
...
| utf8mb4_0900_ai_ci         | NO PAD        |
| utf8mb4_de_pb_0900_ai_ci   | NO PAD        |
| utf8mb4_is_0900_ai_ci      | NO PAD        |
...
| utf8mb4_ja_0900_as_cs      | NO PAD        |
| utf8mb4_ja_0900_as_cs_ks   | NO PAD        |
| utf8mb4_0900_as_ci         | NO PAD        |
| utf8mb4_ru_0900_ai_ci      | NO PAD        |
| utf8mb4_ru_0900_as_cs      | NO PAD        |
| utf8mb4_zh_0900_as_cs      | NO PAD        |
| utf8mb4_0900_bin           | NO PAD        |
+----------------------------+---------------+

Сравнение значений строк, отличных от двоичных (CHAR, VARCHAR и TEXT), которые имеют сортировку NO PAD, отличается от других сортировок по отношению к пробелам в конце. Например, 'a' и 'a ' сравниваются как разные строки, а не как одинаковая строка. Это можно увидеть, используя двоичные сортировки для utf8mb4. Атрибут заполнения для utf8mb4_bin — PAD SPACE, в то время как для utf8mb4_0900_bin он равен NO PAD. Следовательно, операции, включающие utf8mb4_0900_bin, не добавляют пробелы в конце, и сравнения строк с пробелами в конце могут отличаться для этих двух сортировок:

mysql> CREATE TABLE t1 (c CHAR(10) COLLATE utf8mb4_bin);
Query OK, 0 rows affected (0.03 sec)

mysql> INSERT INTO t1 VALUES('a');
Query OK, 1 row affected (0.01 sec)

mysql> SELECT * FROM t1 WHERE c = 'a ';
+------+
| c    |
+------+
| a    |
+------+
1 row in set (0.00 sec)

mysql> ALTER TABLE t1 MODIFY c CHAR(10) COLLATE utf8mb4_0900_bin;
Query OK, 0 rows affected (0.02 sec)
Records: 0  Duplicates: 0  Warnings: 0

mysql> SELECT * FROM t1 WHERE c = 'a ';
Empty set (0.00 sec)

Языковые наборы сортировки

MySQL реализует языковые наборы сортировки Unicode, если порядок, основанный только на Алгоритме сортировки Юникода (UCA), не подходит для какого-либо языка. Языковые наборы сортировки основаны на UCA с дополнительными правилами адаптации к языку. Примеры таких правил приведены далее в этом разделе. Для вопросов о конкретных порядках сортировки языков, http://unicode.org предоставляет диаграммы сортировки Common Locale Data Repository (CLDR) по адресу http://www.unicode.org/cldr/charts/30/collation/index.html.

Например, неязыковые utf8mb4_0900_ai_ci и языковые utf8mb4_LOCALE_0900_ai_ci наборы сортировки Unicode обладают следующими характеристиками:

  • Набор сортировки основан на UCA 9.0.0 и CLDR v30, нечувствителен к регистру и акцентам. Эти характеристики указаны как _0900, _ai и _ci в имени набора сортировки. Исключение: utf8mb4_la_0900_ai_ci не основан на CLDR, так как Классический латинский не определён в CLDR.

  • Набор сортировки работает со всеми символами в диапазоне [U+0, U+10FFFF].

  • Если набор сортировки неязыковой, он сортирует все символы, включая дополнительные, в стандартном порядке (описанном ниже). Если набор сортировки языковой, он сортирует символы языка правильно согласно правилам языка, а символы, не относящиеся к этому языку, в стандартном порядке.

  • По умолчанию набор сортировки сортирует символы, имеющие код, указанный в таблице DUCET (Default Unicode Collation Element Table), согласно значению веса, назначенному в таблице. Набор сортировки сортирует символы, не имеющие кода в таблице DUCET, используя их неявное значение веса, построенное согласно UCA.

  • Для неязыковых наборов сортировки символы в последовательностях сокращений обрабатываются как отдельные символы. Для языковых наборов сортировки сокращения могут изменить порядок сортировки символов.

Набор сортировки, включающий код региона или название языка, указанные в следующей таблице, является языковым набором сортировки. Наборы символов Юникода могут включать наборы сортировки для одного или нескольких из этих языков.

Таблица 12.3 Языковые спецификаторы сортировки Unicode

Таблица 12.3 Языковые спецификаторы сортировки Unicode
Язык Языковой спецификатор
Боснийский bs
Болгарский bg
Китайский zh
Классический латинский la или roman
Хорватский hr или croatian
Чешский cs или czech
Датский da или danish
Эсперанто eo или esperanto
Эстонский et или estonian
Галисийский gl
Немецкий (порядок телефонного справочника) de_pb или german2
Венгерский hu или hungarian
Исландский is или icelandic
Японский ja
Латвийский lv или latvian
Литовский lt или lithuanian
Монгольский mn
Норвежский (букмол) nb
Норвежский (нюнорск) nn
Персидский persian
Польский pl или polish
Румынский ro или romanian
Русский ru
Сербский sr
Сингальский sinhala
Словацкий sk или slovak
Словенский sl или slovenian
Современный испанский es или spanish
Традиционный испанский es_trad или spanish2
Шведский sv или swedish
Турецкий tr или turkish
Вьетнамский vi или vietnamese

MySQL предоставляет болгарские наборы сортировки utf8mb4_bg_0900_ai_ci и utf8mb4_bg_0900_as_cs.

Хорватские наборы сортировки адаптированы для этих хорватских букв: Č, Ć, Dž, Đ, Lj, Nj, Š, Ž.

MySQL предоставляет наборы сортировки utf8mb4_sr_latn_0900_ai_ci и utf8mb4_sr_latn_0900_as_cs для сербского языка и наборы сортировки utf8mb4_bs_0900_ai_ci и utf8mb4_bs_0900_as_cs для боснийского языка, когда эти языки написаны латинским алфавитом.

MySQL предоставляет наборы сортировки для обоих основных разновидностей норвежского языка: для букмола можно использовать utf8mb4_nb_0900_ai_ci и utf8mb4_nb_0900_as_cs; для нюнорска MySQL теперь предоставляет utf8mb4_nn_0900_ai_ci и utf8mb4_nn_0900_as_cs.

Для японского языка набор символов utf8mb4 включает наборы сортировки utf8mb4_ja_0900_as_cs и utf8mb4_ja_0900_as_cs_ks. Оба набора сортировки чувствительны к регистру и акцентам. utf8mb4_ja_0900_as_cs_ks также чувствителен к кане и различает символы катаканы и хираганы, в то время как utf8mb4_ja_0900_as_cs рассматривает символы катаканы и хираганы как равные при сортировке. Приложения, которым требуется японский набор сортировки, но не чувствительность к кане, могут использовать utf8mb4_ja_0900_as_cs для лучшей производительности сортировки. utf8mb4_ja_0900_as_cs использует три уровня веса для сортировки; utf8mb4_ja_0900_as_cs_ks использует четыре.

Для классических латинских наборов сортировки, нечувствительных к акцентам, I и J сравниваются как равные, а U и V сравниваются как равные. I и J, а также U и V сравниваются как равные на уровне базовой буквы. Другими словами, J рассматривается как акцентированная I, а U рассматривается как акцентированная V.

MySQL предоставляет наборы сортировки для монгольского языка, написанного кириллицей, utf8mb4_mn_cyrl_0900_ai_ci и utf8mb4_mn_cyrl_0900_as_cs.

Доступны наборы сортировки для современного и традиционного испанского. Для обоих, ñ (тильда) – отдельная буква между n и o. Кроме того, для традиционного испанского, ch — отдельная буква между c и d, а ll — отдельная буква между l и m.

Наборы сортировки традиционного испанского также могут использоваться для астурийского и галисийского языков. MySQL также предоставляет наборы сортировки utf8mb4_gl_0900_ai_ci и utf8mb4_gl_0900_as_cs для галисийского языка. (Это те же наборы сортировки, что и utf8mb4_es_0900_ai_ci и utf8mb4_es_0900_as_cs соответственно.)

Шведские наборы сортировки включают шведские правила. Например, в шведском языке существует следующая взаимосвязь, которая не ожидается от говорящих на немецком или французском языке:

Ü = Y < Ö

Сортировки _general_ci и _unicode_ci

Для любого набора символов Юникод операции, выполняемые с помощью сортировки xxx_general_ci, выполняются быстрее, чем операции с сортировкой xxx_unicode_ci. Например, сравнения с помощью сортировки utf8mb4_general_ci выполняются быстрее, но немного менее точно, чем сравнения с помощью utf8mb4_unicode_ci. Причина в том, что utf8mb4_unicode_ci поддерживает такие отображения, как расширения; то есть, когда один символ сравнивается как равный комбинациям других символов. Например, ß равен ss в немецком и некоторых других языках. utf8mb4_unicode_ci также поддерживает сокращения и игнорируемые символы. utf8mb4_general_ci — это сортировка, унаследованная от предыдущих версий, которая не поддерживает расширения, сокращения или игнорируемые символы. Она может производить только однозначные сравнения между символами.

Для наглядности, следующие равенства верны как в utf8mb4_general_ci, так и в utf8mb4_unicode_ci (для эффекта этого в сравнениях или поисках см. Раздел 12.8.6, «Примеры эффекта сортировки»):

Ä = A
Ö = O
Ü = U

Различие между сортировками заключается в том, что это верно для utf8mb4_general_ci:

ß = s

В то время как это верно для utf8mb4_unicode_ci, которая поддерживает немецкий порядок DIN-1 (также известный как лексикографический порядок):

ß = ss

MySQL реализует языковые сортировки Юникод, если порядок с использованием utf8mb4_unicode_ci не подходит для языка. Например, utf8mb4_unicode_ci подходит для немецкого лексикографического порядка и французского, поэтому нет необходимости создавать специальные сортировки utf8mb4.

utf8mb4_general_ci также подходит как для немецкого, так и для французского, за исключением того, что ß равен s, а не ss. Если это приемлемо для вашего приложения, вы должны использовать utf8mb4_general_ci, так как она быстрее. Если это неприемлемо (например, если вам нужен немецкий лексикографический порядок), используйте utf8mb4_unicode_ci, так как она более точна.

Если вам нужен немецкий порядок DIN-2 (по алфавиту), используйте сортировку utf8mb4_german2_ci, которая сравнивает следующие наборы символов как равные:

Ä = Æ = AE
Ö = Œ = OE
Ü = UE
ß = ss

utf8mb4_german2_ci похожа на latin1_german2_ci, но последняя не считает Æ равным AE или Œ равным OE. Нет сортировки utf8mb4_german_ci, соответствующей latin1_german_ci для немецкого лексикографического порядка, потому что utf8mb4_general_ci вполне достаточно.

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

Вес сортировки символа определяется следующим образом:

  • Для всех сортировок Юникод, за исключением сортировок _bin (двоичных), MySQL выполняет поиск в таблице, чтобы найти вес сортировки символа.

  • Для сортировок _bin, за исключением utf8mb4_0900_bin, вес основан на кодовом значении, возможно, с добавленными ведущими нулевыми байтами.

  • Для utf8mb4_0900_bin вес — это байты кодировки utf8mb4. Порядок сортировки такой же, как и для utf8mb4_bin, но намного быстрее.

Веса сортировки можно отобразить с помощью функции WEIGHT_STRING(). (См. Раздел 14.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 отличался бы от порядка в utf8mb4_bin. Например, следующая таблица показывает два редких символа. Первый символ находится в диапазоне E000-FFFF, поэтому он больше суррогата, но меньше дополнительного. Второй символ — дополнительный.

Code point  Character                    utf8mb4      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. И они отсортированы по весу utf8mb4, потому что 0xef < 0xf0. Но они не отсортированы по весу utf16, если мы используем байтовое сравнение, потому что 0xff > 0xd8.

Таким образом, сортировка utf16_bin MySQL не “байт за байтом”, а “по кодовому значению”. Когда MySQL видит кодировку дополнительного символа в utf16, она преобразует её в кодовое значение символа и затем сравнивает. Поэтому utf8mb4_bin и utf16_bin имеют одинаковый порядок. Это соответствует требованию стандарта SQL:2008 для сортировки UCS_BASIC: “UCS_BASIC — это сортировка, в которой порядок определяется исключительно скалярными значениями Юникода символов в сортируемых строках. Она применима к набору символов UCS. Поскольку каждый набор символов является подмножеством набора символов UCS, сортировка UCS_BASIC потенциально применима ко всем наборам символов. ПРИМЕЧАНИЕ 11: Скалярное значение Юникода символа — это его кодовое значение, рассматриваемое как целое без знака.”

Если набор символов — 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-8.4-en/charset-unicode-sets.html

Spec-Zone.ru

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