Spec-Zone.ru › MySQL 9.2

12.14.1 Типы реализации сортировок

MySQL реализует несколько типов сортировок:

Простые сортировки для 8-битных наборов символов

Этот тип сортировки реализован с помощью массива из 256 весов, который определяет взаимно однозначное соответствие между кодами символов и весами. latin1_swedish_ci — пример. Это сортировка без учёта регистра, поэтому прописные и строчные версии символа имеют одинаковые веса и сравниваются как равные.

mysql> SET NAMES 'latin1' COLLATE 'latin1_swedish_ci';
Query OK, 0 rows affected (0.01 sec)

mysql> SELECT HEX(WEIGHT_STRING('a')), HEX(WEIGHT_STRING('A'));
+-------------------------+-------------------------+
| HEX(WEIGHT_STRING('a')) | HEX(WEIGHT_STRING('A')) |
+-------------------------+-------------------------+
| 41                      | 41                      |
+-------------------------+-------------------------+
1 row in set (0.01 sec)

mysql> SELECT 'a' = 'A';
+-----------+
| 'a' = 'A' |
+-----------+
|         1 |
+-----------+
1 row in set (0.12 sec)

Инструкции по реализации см. в Разделе 12.14.3, «Добавление простой сортировки к 8-битному набору символов».

Сложные сортировки для 8-битных наборов символов

Этот тип сортировки реализован с помощью функций в файле исходного кода C, которые определяют порядок символов, как описано в Разделе 12.13, «Добавление набора символов».

Сортировки для многобайтовых наборов символов, не являющихся Unicode

Для этого типа сортировки 8-битные (однобайтовые) и многобайтовые символы обрабатываются по-разному. Для 8-битных символов коды символов отображаются на веса с учётом регистра. (Например, однобайтовые символы 'a' и 'A' оба имеют вес 0x41.) Для многобайтовых символов существует два типа отношений между кодами символов и весами:

  • Веса равны кодам символов. sjis_japanese_ci — пример такого типа сортировки. Многобайтовый символ 'ぢ' имеет код символа 0x82C0, и вес также равен 0x82C0.

    mysql> CREATE TABLE t1
           (c1 VARCHAR(2) CHARACTER SET sjis COLLATE sjis_japanese_ci);
    Query OK, 0 rows affected (0.01 sec)
    
    mysql> INSERT INTO t1 VALUES ('a'),('A'),(0x82C0);
    Query OK, 3 rows affected (0.00 sec)
    Records: 3  Duplicates: 0  Warnings: 0
    
    mysql> SELECT c1, HEX(c1), HEX(WEIGHT_STRING(c1)) FROM t1;
    +------+---------+------------------------+
    | c1   | HEX(c1) | HEX(WEIGHT_STRING(c1)) |
    +------+---------+------------------------+
    | a    | 61      | 41                     |
    | A    | 41      | 41                     |
    | ぢ    | 82C0    | 82C0                   |
    +------+---------+------------------------+
    3 rows in set (0.00 sec)
    
  • Коды символов отображаются взаимно однозначно на веса, но код не обязательно равен весу. gbk_chinese_ci — пример такого типа сортировки. Многобайтовый символ '膰' имеет код символа 0x81B0, но вес равен 0xC286.

    mysql> CREATE TABLE t1
           (c1 VARCHAR(2) CHARACTER SET gbk COLLATE gbk_chinese_ci);
    Query OK, 0 rows affected (0.33 sec)
    
    mysql> INSERT INTO t1 VALUES ('a'),('A'),(0x81B0);
    Query OK, 3 rows affected (0.00 sec)
    Records: 3  Duplicates: 0  Warnings: 0
    
    mysql> SELECT c1, HEX(c1), HEX(WEIGHT_STRING(c1)) FROM t1;
    +------+---------+------------------------+
    | c1   | HEX(c1) | HEX(WEIGHT_STRING(c1)) |
    +------+---------+------------------------+
    | a    | 61      | 41                     |
    | A    | 41      | 41                     |
    | 膰    | 81B0    | C286                   |
    +------+---------+------------------------+
    3 rows in set (0.00 sec)
    

Инструкции по реализации см. в Разделе 12.13, «Добавление набора символов».

Сортировки для многобайтовых наборов символов Unicode

Некоторые из этих сортировок основаны на алгоритме сортировки Unicode (UCA), другие — нет.

Сортировки, не основанные на UCA, имеют взаимно однозначное соответствие между кодом символа и весом. В MySQL такие сортировки не учитывают регистр и знаки ударения. utf8mb4_general_ci — пример: 'a', 'A', 'À' и 'á' имеют разные коды символов, но все имеют вес 0x0041 и сравниваются как равные.

mysql> SET NAMES 'utf8mb4' COLLATE 'utf8mb4_general_ci';
Query OK, 0 rows affected (0.00 sec)

mysql> CREATE TABLE t1
       (c1 CHAR(1) CHARACTER SET UTF8MB4 COLLATE utf8mb4_general_ci);
Query OK, 0 rows affected (0.01 sec)

mysql> INSERT INTO t1 VALUES ('a'),('A'),('À'),('á');
Query OK, 4 rows affected (0.00 sec)
Records: 4  Duplicates: 0  Warnings: 0

mysql> SELECT c1, HEX(c1), HEX(WEIGHT_STRING(c1)) FROM t1;
+------+---------+------------------------+
| c1   | HEX(c1) | HEX(WEIGHT_STRING(c1)) |
+------+---------+------------------------+
| a    | 61      | 0041                   |
| A    | 41      | 0041                   |
| À    | C380    | 0041                   |
| á    | C3A1    | 0041                   |
+------+---------+------------------------+
4 rows in set (0.00 sec)

Сортировки, основанные на UCA в MySQL, обладают следующими свойствами:

  • Если символ имеет веса, каждый вес использует 2 байта (16 бит).

  • Символ может иметь ноль весов (или пустой вес). В этом случае символ игнорируется. Пример: "U+0000 NULL" не имеет веса и игнорируется.

  • Символ может иметь один вес. Пример: 'a' имеет вес 0x0E33.

    mysql> SET NAMES 'utf8mb4' COLLATE 'utf8mb4_unicode_ci';
    Query OK, 0 rows affected (0.05 sec)
    
    mysql> SELECT HEX('a'), HEX(WEIGHT_STRING('a'));
    +----------+-------------------------+
    | HEX('a') | HEX(WEIGHT_STRING('a')) |
    +----------+-------------------------+
    | 61       | 0E33                    |
    +----------+-------------------------+
    1 row in set (0.02 sec)
    
  • Символ может иметь несколько весов. Это расширение. Пример: немецкая буква 'ß' (лигатура SZ или SHARP S) имеет вес 0x0FEA0FEA.

    mysql> SET NAMES 'utf8mb4' COLLATE 'utf8mb4_unicode_ci';
    Query OK, 0 rows affected (0.11 sec)
    
    mysql> SELECT HEX('ß'), HEX(WEIGHT_STRING('ß'));
    +-----------+--------------------------+
    | HEX('ß')  | HEX(WEIGHT_STRING('ß'))  |
    +-----------+--------------------------+
    | C39F      | 0FEA0FEA                 |
    +-----------+--------------------------+
    1 row in set (0.00 sec)
    
  • Несколько символов могут иметь один вес. Это сокращение. Пример: 'ch' — это единственная буква в чешском языке и имеет вес 0x0EE2.

    mysql> SET NAMES 'utf8mb4' COLLATE 'utf8mb4_czech_ci';
    Query OK, 0 rows affected (0.09 sec)
    
    mysql> SELECT HEX('ch'), HEX(WEIGHT_STRING('ch'));
    +-----------+--------------------------+
    | HEX('ch') | HEX(WEIGHT_STRING('ch')) |
    +-----------+--------------------------+
    | 6368      | 0EE2                     |
    +-----------+--------------------------+
    1 row in set (0.00 sec)
    

Возможна и ситуация, когда многим символам соответствует множество весов (это сочетание сокращения и расширения), но MySQL её не поддерживает.

Инструкции по реализации сортировки, не основанной на UCA, см. в Разделе 12.13, «Добавление набора символов». Для сортировки, основанной на UCA, см. Раздел 12.14.4, «Добавление сортировки UCA к набору символов Unicode».

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

Существуют также несколько сортировок, которые не попадают ни в одну из предыдущих категорий.

© 2025 Oracle
Licensed under the GPLv2 License.
https://docs.oracle.com/cd/E17952_01/mysql-8.4-en/charset-collation-implementations.html

Spec-Zone.ru

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