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.