Spec-Zone .ru
спецификации, руководства, описания, API

10.1.7.9. Сопоставление и INFORMATION_SCHEMA Поискы

Строковые столбцы в INFORMATION_SCHEMA у таблиц есть сопоставление utf8_general_ci, который является нечувствительным к регистру. Однако, поискы в INFORMATION_SCHEMA на строковые столбцы также влияет чувствительность к регистру файловой системы. Для значений, которые соответствуют объектам, которые представляются в файловой системе, такой как имена баз данных и таблиц, поискы могут быть чувствительными к регистру, если файловая система является чувствительной к регистру. Этот раздел описывает, как работать вокруг этой проблемы в случае необходимости; см. также Ошибку #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        |+-------------+1 row in set (0.01 sec)mysql> SELECT SCHEMA_NAME FROM INFORMATION_SCHEMA.SCHEMATA    -> WHERE SCHEMA_NAME = 'TEST';Empty set (0.00 sec)

На Windows или Mac OS X, где файловые системы не являются чувствительными к регистру, сравнения соответствуют обоим 'test' и 'TEST':

mysql> SELECT SCHEMA_NAME FROM
        INFORMATION_SCHEMA.SCHEMATA    -> WHERE SCHEMA_NAME =
        'test';+-------------+| SCHEMA_NAME |+-------------+| test        |+-------------+1 row in set (0.00 sec)mysql> SELECT SCHEMA_NAME FROM INFORMATION_SCHEMA.SCHEMATA    -> WHERE SCHEMA_NAME = 'TEST';+-------------+| SCHEMA_NAME |+-------------+| TEST        |+-------------+1 row in set (0.00 sec)

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

Это поведение происходит потому что utf8_general_ci сопоставление не используется для INFORMATION_SCHEMA запросы, ища файловую систему объекты базы данных. Это - результат оптимизации, реализованной для INFORMATION_SCHEMA поискы в MySQL. Для получения информации об этой оптимизации см. Раздел 8.2.4, "Оптимизируя INFORMATION_SCHEMA Запросы".

Поискы в 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 |+--------------------+1 row in set (0.00 sec)mysql> SELECT SCHEMA_NAME FROM INFORMATION_SCHEMA.SCHEMATA    -> WHERE SCHEMA_NAME = 'INFORMATION_SCHEMA';+--------------------+| SCHEMA_NAME        |+--------------------+| information_schema |+--------------------+1 row in set (0.00 sec)

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

mysql> SELECT SCHEMA_NAME FROM
        INFORMATION_SCHEMA.SCHEMATA    -> WHERE SCHEMA_NAME COLLATE
        utf8_general_ci = 'test';+-------------+| SCHEMA_NAME |+-------------+| test        |+-------------+1 row in set (0.00 sec)mysql> SELECT SCHEMA_NAME FROM INFORMATION_SCHEMA.SCHEMATA    -> WHERE SCHEMA_NAME COLLATE utf8_general_ci = 'TEST';| SCHEMA_NAME |+-------------+| test        |+-------------+1 row in set (0.00 sec)

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

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

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

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'

Первое из тех сравнений (с utf8_bin) является чувствительным к регистру; другие не.