Spec-Zone.ru › MySQL 5.7

10.8.7 Использование сортировки в запросах INFORMATION_SCHEMA

Столбцы строкового типа в таблицах INFORMATION_SCHEMA имеют сортировку utf8_general_ci, которая нечувствительна к регистру. Однако для значений, соответствующих объектам, представленным в файловой системе, таким как базы данных и таблицы, поиск в столбцах строкового типа INFORMATION_SCHEMA может быть чувствительным или нечувствительным к регистру в зависимости от особенностей файловой системы и значения системной переменной lower_case_table_names. Например, поиск может быть чувствительным к регистру, если файловая система чувствительна к регистру. Этот раздел описывает это поведение и способы его изменения при необходимости; см. также ошибку #34921.

Предположим, что запрос ищет в столбце SCHEMATA.SCHEMA_NAME базу данных test. В Linux файловые системы чувствительны к регистру, поэтому сравнения SCHEMATA.SCHEMA_NAME с 'test' совпадают, но сравнения с 'TEST' не совпадают:

mysql> SELECT SCHEMA_NAME FROM INFORMATION_SCHEMA.SCHEMATA
       WHERE SCHEMA_NAME = 'test';
+-------------+
| SCHEMA_NAME |
+-------------+
| test        |
+-------------+

mysql> SELECT SCHEMA_NAME FROM INFORMATION_SCHEMA.SCHEMATA
       WHERE SCHEMA_NAME = 'TEST';
Empty set (0.00 sec)

Эти результаты возникают при значении системной переменной lower_case_table_names, установленной в 0. Изменение значения lower_case_table_names на 1 или 2 приводит к тому, что второй запрос возвращает тот же (непустой) результат, что и первый запрос.

В Windows или macOS файловые системы нечувствительны к регистру, поэтому сравнения совпадают как для 'test', так и для 'TEST':

mysql> SELECT SCHEMA_NAME FROM INFORMATION_SCHEMA.SCHEMATA
       WHERE SCHEMA_NAME = 'test';
+-------------+
| SCHEMA_NAME |
+-------------+
| test        |
+-------------+

mysql> SELECT SCHEMA_NAME FROM INFORMATION_SCHEMA.SCHEMATA
       WHERE SCHEMA_NAME = 'TEST';
+-------------+
| SCHEMA_NAME |
+-------------+
| TEST        |
+-------------+

Значение lower_case_table_names в этом контексте не имеет значения.

Это поведение возникает потому, что сортировка utf8_general_ci не используется для запросов INFORMATION_SCHEMA при поиске значений, соответствующих объектам, представленным в файловой системе. Это результат оптимизаций сканирования файловой системы, реализованных для запросов INFORMATION_SCHEMA. Сведения об этих оптимизациях см. в разделе 8.2.3, «Оптимизация запросов INFORMATION_SCHEMA».

Если результат строковой операции над столбцом INFORMATION_SCHEMA отличается от ожидаемого, можно обойти эту проблему, используя явное условие COLLATE для принудительного использования подходящей сортировки (см. раздел 10.8.1, «Использование COLLATE в операторах SQL»). Например, для выполнения поиска, нечувствительного к регистру, используйте COLLATE для имени столбца INFORMATION_SCHEMA:

mysql> SELECT SCHEMA_NAME FROM INFORMATION_SCHEMA.SCHEMATA
       WHERE SCHEMA_NAME COLLATE utf8_general_ci = 'test';
+-------------+
| SCHEMA_NAME |
+-------------+
| test        |
+-------------+

mysql> SELECT SCHEMA_NAME FROM INFORMATION_SCHEMA.SCHEMATA
       WHERE SCHEMA_NAME COLLATE utf8_general_ci = 'TEST';
+-------------+
| SCHEMA_NAME |
+-------------+
| test        |
+-------------+

В предыдущих запросах важно применять условие COLLATE к имени столбца INFORMATION_SCHEMA. Применение COLLATE к значению сравнения не оказывает никакого влияния.

Можно также использовать функцию UPPER() или LOWER():

WHERE UPPER(SCHEMA_NAME) = 'TEST'
WHERE LOWER(SCHEMA_NAME) = 'test'

Хотя сравнение, нечувствительное к регистру, может выполняться даже на платформах с файловыми системами, чувствительными к регистру, как только что показано, это не всегда правильное решение. На таких платформах могут существовать несколько объектов с именами, отличающимися только регистром букв. Например, таблицы с именами city, CITY и City могут одновременно существовать. Подумайте, нужно ли запрос должен находить все такие имена или только одно, и составьте запросы соответственно. Первое из следующих сравнений (с utf8_bin) чувствительно к регистру, остальные — нет:

WHERE TABLE_NAME COLLATE utf8_bin = 'City'
WHERE TABLE_NAME COLLATE utf8_general_ci = 'city'
WHERE UPPER(TABLE_NAME) = 'CITY'
WHERE LOWER(TABLE_NAME) = 'city'

Поиск в столбцах строкового типа INFORMATION_SCHEMA для значений, относящихся к самой INFORMATION_SCHEMA, использует сортировку utf8_general_ci, потому что INFORMATION_SCHEMA — это «виртуальная» база данных, не представленная в файловой системе. Например, сравнения с SCHEMATA.SCHEMA_NAME совпадают с 'information_schema' или 'INFORMATION_SCHEMA' независимо от платформы:

mysql> SELECT SCHEMA_NAME FROM INFORMATION_SCHEMA.SCHEMATA
       WHERE SCHEMA_NAME = 'information_schema';
+--------------------+
| SCHEMA_NAME        |
+--------------------+
| information_schema |
+--------------------+

mysql> SELECT SCHEMA_NAME FROM INFORMATION_SCHEMA.SCHEMATA
       WHERE SCHEMA_NAME = 'INFORMATION_SCHEMA';
+--------------------+
| SCHEMA_NAME        |
+--------------------+
| information_schema |
+--------------------+

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

Spec-Zone.ru

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