Поведение на SELECT на information_schema.routines въз основа на системна променлива small_case_table_names

Това е заявката, която използвам, за да получа списък със съхранени процедури в MySQL база данни.

SELECT `SPECIFIC_NAME` FROM `INFORMATION_SCHEMA`.`ROUTINES` WHERE `ROUTINE_SCHEMA` = 'database_name' COLLATE utf8_bin AND ROUTINE_TYPE = 'PROCEDURE'; 

Принуждавам utf8_bin като сортиране, което да се използва, за да получа правилния резултат, ако системната променлива lower_case_table_names е настроена на 0.

Но получавам празен набор от резултати със същата заявка, ако lower_case_table_names е зададено на 2 и името на базата данни има главни букви.

Също така, ако lower_case_table_names е настроено на 0 в система, която има имена на файлове, които не са чувствителни към регистър, получавам празен набор от резултати със заявката.

И в двата случая, ако "COLLATE utf8_bin" се премахне от заявката или се замени с "COLLATE utf8_general_ci", получавам правилния набор от резултати.

Цитирам от: http://dev.mysql.com/doc/refman/5.6/en/identifier-case-sensitivity.html

  • 0
    Имената на таблици и бази данни се съхраняват на диск с помощта на главни букви, указани в израза CREATE TABLE или CREATE DATABASE. Сравненията на имена са чувствителни към главни и малки букви. Не трябва да задавате тази променлива на 0, ако изпълнявате MySQL на система, която има имена на файлове, които не са чувствителни към малки и главни букви (като Windows или Mac OS X). Ако принудите тази променлива да бъде 0 с --lower-case-table-names=0 на файлова система, която не е чувствителна към главни и малки букви, и осъществите достъп до имената на таблици MyISAM с различни главни букви, може да се получи повреда на индекса.

  • 1
    Имената на таблиците се съхраняват с малки букви на диска и сравненията на имена не са чувствителни към главни и малки букви. MySQL преобразува всички имена на таблици в малки букви при съхранение и търсене. Това поведение се отнася и за имена на бази данни и псевдоними на таблици.

  • 2
    Имената на таблици и бази данни се съхраняват на диска, като се използват главни букви, посочени в оператора CREATE TABLE или CREATE DATABASE, но MySQL ги преобразува в малки букви при търсене. Сравненията на имена не са чувствителни към главни и малки букви. Това работи само на файлови системи, които не са чувствителни към главни и малки букви! Имената на таблиците в InnoDB се съхраняват с малки букви, както за small_case_table_names=1.

Ако small_case_table_names е зададено на 2

„MySQL ги преобразува в малки букви при търсене“

Какво означава това?

Знам, че small_case_table_names не трябва да се задава на 0 на Windows/OS X, но нямам контрол върху средата, в която ще се изпълнява заявката.

Но намирам поведението за странно.

SELECT на INFORMATION_SCHEMA.EVENTS също се държи по същия начин.

АКТУАЛИЗАЦИЯ

Стойностите в колоната ROUTINE_SCHEMA в таблицата INFORMATION_SCHEMA.ROUTINES са с малки букви, ако small_case_table_names = 2 или когато small_case_table_names = 0 в windows. Но колоната ROUTINE_SCHEMA в INFORMATION_SCHEMA.TABLES има стойности със същите главни букви, както е използвано при създаването на базата данни. Дори наборът от резултати от SHOW DATABASES има стойности със същите главни букви, както е използвано при създаването на базата данни. Защо тази разлика?


person user1391868    schedule 10.01.2014    source източник
comment
Защо тази разлика? - звучи вероятно като грешка.   -  person eggyal    schedule 11.01.2014


Отговори (1)


Стойността на lower_case_table_names засяга две неща:

  • главните букви, използвани за имената на файловете с данни, съхранявани на диска; и

  • имплицитна трансформация на идентификатори на обекти на схема в SQL команди.

Вашият проблем е, че когато правите заявка за INFORMATION_SCHEMA, единствените идентификатори на обект на схема са препратките към самия INFORMATION_SCHEMA (във заявката ви таблицата ROUTINES и нейните имена на колони). Препратките към вашите обекти на схема (напр. стойности в колоната ROUTINE_SCHEMA и вашият 'database_name' литерал и т.н.) не са идентификатори на обект на схема, а по-скоро обикновени низове (които не се възползват от Неявната трансформация на буквени букви на MySQL според системната променлива lower_case_table_names).

И така, с lower_case_table_names = 2, вашата база данни се съхранява на диск (и в INFORMATION_SCHEMA) с помощта на главни букви, използвани в командата CREATE DATABASE. Ако използвате сортиране, чувствително към главни и малки букви, когато правите заявка за INFORMATION_SCHEMA, справките разбираемо ще се провалят (освен ако не използвате същата буква, използвана при създаването на базата данни). Решението очевидно е да се използва съпоставка, която не е чувствителна към главни и малки букви, като utf8_general_ci.

person eggyal    schedule 10.01.2014