Spec-Zone.ru › MySQL 8.4

12.8.4 Принудительная привязка сортировки в выражениях

В подавляющем большинстве случаев очевидно, какую сортировку MySQL использует для разрешения операции сравнения. Например, в следующих случаях должно быть ясно, что сортировка — это сортировка столбца x:

SELECT x FROM T ORDER BY x;
SELECT x FROM T WHERE x = x;
SELECT DISTINCT x FROM T;

Однако при нескольких операндах может возникнуть неоднозначность. Например, это утверждение выполняет сравнение между столбцом x и строковой литералом 'Y':

SELECT x FROM T WHERE x = 'Y';

Если у x и 'Y' одинаковая сортировка, нет неоднозначности относительно сортировки, используемой для сравнения. Но если у них разные сортировки, должна ли сравнение использовать сортировку x или 'Y'? У обоих x и 'Y' есть сортировки, так какая сортировка имеет приоритет?

Смешение сортировок может также произойти в контекстах, отличных от сравнения. Например, операция конкатенации с несколькими аргументами, такая как CONCAT(x,'Y'), объединяет свои аргументы для получения одной строки. Какой сортировкой должна обладать результат?

Для разрешения таких вопросов MySQL проверяет, можно ли привести сортировку одного элемента к сортировке другого. MySQL присваивает значения принудительной привязки следующим образом:

  • Явное COLLATE предложение имеет принудительную привязку 0 (вообще не приводимо).

  • Конкатенация двух строк с разными сортировками имеет принудительную привязку 1.

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

  • «“система константа”» (строка, возвращаемая функциями, такими как USER() или VERSION()) имеет принудительную привязку 3.

  • Сортировка литерала имеет принудительную привязку 4.

  • Сортировка числового или временного значения имеет принудительную привязку 5.

  • NULL или выражение, полученное из NULL, имеет принудительную привязку 6.

MySQL использует значения принудительной привязки по следующим правилам, чтобы разрешить неоднозначность:

  • Используйте сортировку с наименьшим значением принудительной привязки.

  • Если у обеих сторон одинаковая принудительная привязка, то:

    • Если обе стороны — Unicode или обе стороны не Unicode, это ошибка.

    • Если одна из сторон имеет наборы символов Unicode, а другая сторона — наборы символов не Unicode, сторона с наборами символов Unicode выигрывает, и выполняется автоматическое преобразование набора символов для стороны с наборами символов не Unicode. Например, следующее утверждение не возвращает ошибку:

      SELECT CONCAT(utf8mb4_column, latin1_column) FROM t1;
      

      Возвращается результат, имеющий набор символов utf8mb4 и ту же сортировку, что и utf8mb4_column. Значения latin1_column автоматически преобразуются в utf8mb4 перед конкатенацией.

    • Для операции с операндами из одного набора символов, но смешивающими сортировку _bin и сортировку _ci или _cs, используется сортировка _bin. Это аналогично тому, как операции, которые смешивают небинарные и бинарные строки, обрабатывают операнды как бинарные строки, примененные к сортировкам, а не к типам данных.

Хотя автоматическое преобразование не входит в стандарт SQL, в стандарте говорится, что каждый набор символов (с точки зрения поддерживаемых символов) является «подмножеством» Unicode. Поскольку это хорошо известный принцип, что «то, что применяется к супермножеству, может применяться к подмножеству», мы считаем, что сортировка для Unicode может применяться для сравнений со строками не Unicode. Более общо, MySQL использует концепцию репертуара наборов символов, которая иногда может использоваться для определения отношений подмножества между наборами символов и для выполнения преобразования операндов в операциях, которые в противном случае вызывали бы ошибку. См. Раздел 12.2.1, «Репертуар наборов символов».

Следующая таблица иллюстрирует некоторые применения вышеперечисленных правил.

Сравнение Используемая сортировка
column1 = 'A' Использовать сортировку column1
column1 = 'A' COLLATE x Использовать сортировку 'A' COLLATE x
column1 COLLATE x = 'A' COLLATE y Ошибка

Для определения принудительной привязки строкового выражения используйте функцию COERCIBILITY() (см. Раздел 14.15, «Функции информации»):

mysql> SELECT COERCIBILITY(_utf8mb4'A' COLLATE utf8mb4_bin);
        -> 0
mysql> SELECT COERCIBILITY(VERSION());
        -> 3
mysql> SELECT COERCIBILITY('A');
        -> 4
mysql> SELECT COERCIBILITY(1000);
        -> 5
mysql> SELECT COERCIBILITY(NULL);
        -> 6

Для неявного преобразования числового или временного значения в строку, такого как происходит для аргумента 1 в выражении CONCAT(1, 'abc'), результатом является строка символов (не бинарная), которая имеет набор символов и сортировку, определяемые переменными системы character_set_connection и collation_connection. См. Раздел 14.3, «Преобразование типов в оценке выражения».

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

Spec-Zone.ru

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