#php #mysql
#mysql #чувствителен к регистру #mysql-8.0
Вопрос:
при запуске
SELECT maxlen FROM `information_schema`.`CHARACTER_SETS`;
mysql 5.7 и mysql 8 дают разные результаты:
- в mysql 5.7 имена строк результатов указаны в нижнем регистре,
- в mysql 8 имена строк результатов указаны в верхнем регистре.
ПРИМЕЧАНИЕ: в CHARACTER_SETS
таблице имя MAXLEN
столбца (в верхнем регистре).
Поскольку я не могу найти ресурс, документирующий это, мой вопрос :
каковы изменения в наборе строк результатов mysql 8?
Комментарии:
1. примечание: я отказался от редактирования в заголовке вопроса, потому что мой вопрос должен быть общим: я обнаружил симптом ont, я хочу знать, в чем причина.
Ответ №1:
MySQL 8.0 изменил реализацию некоторых представлений в INFORMATION_SCHEMA:
https://mysqlserverteam.com/mysql-8-0-improvements-to-information_schema / говорит:
Теперь, когда метаданные всех таблиц базы данных хранятся в таблицах словаря транзакционных данных, это позволяет нам создавать таблицу INFORMATION_SCHEMA как представление базы данных поверх таблиц словаря данных. Это устраняет такие затраты, как создание временных таблиц для каждого запроса INFORMATION_SCHEMA во время выполнения «на лету», а также сканирование каталогов файловой системы для поиска файлов FRM. Также теперь можно использовать всю мощь оптимизатора MySQL для подготовки лучших планов выполнения запросов с использованием индексов в таблицах словаря данных.
Итак, это делается по уважительным причинам, но я понимаю, что это расстроило некоторые ваши запросы, когда вы извлекаете результаты в ассоциативных массивах на основе имени столбца.
Вы можете видеть, что определение представления явно объявляет имя столбца в верхнем регистре:
mysql 8.0.14> SHOW CREATE VIEW CHARACTER_SETSG
*************************** 1. row ***************************
View: CHARACTER_SETS
Create View: CREATE ALGORITHM=UNDEFINED DEFINER=`mysql.infoschema`@`localhost` SQL SECURITY DEFINER VIEW `CHARACTER_SETS` AS
select
`cs`.`name` AS `CHARACTER_SET_NAME`,
`col`.`name` AS `DEFAULT_COLLATE_NAME`,
`cs`.`comment` AS `DESCRIPTION`,
`cs`.`mb_max_length` AS `MAXLEN` -- delimited column explicitly uppercase
from (`mysql`.`character_sets` `cs`
join `mysql`.`collations` `col` on((`cs`.`default_collation_id` = `col`.`id`)))
character_set_client: utf8
collation_connection: utf8_general_ci
Вы можете обойти это изменение несколькими способами:
Вы можете объявлять свои собственные псевдонимы столбцов в нужном вам случае при запросе представления:
mysql 8.0.14> SELECT MAXLEN AS `maxlen`
FROM `information_schema`.`CHARACTER_SETS` LIMIT 2;
--------
| maxlen |
--------
| 2 |
| 1 |
--------
Вы могли бы начать привычку запрашивать столбцы в верхнем регистре до версии 8.0. Вот тест, показывающий результаты в моей песочнице 5.7:
mysql 5.7.24> SELECT MAXLEN
FROM `information_schema`.`CHARACTER_SETS` LIMIT 2;
--------
| MAXLEN |
--------
| 2 |
| 1 |
--------
Или вы могли бы извлекать результаты в неассоциативный массив и ссылаться на столбцы по номеру столбца, а не по имени.
Комментарии:
1. Из того, что вы говорите, я вывожу это поведение в наборе строк результатов в mysql 5.7 и mysql 8 -1- view : регистр имени столбца должен быть принудительно установлен с использованием псевдонима. -регистр имени столбца 2-таблицы используется в выборке
2. И, пожалуйста, есть ли у вас ссылка, документирующая это поведение?
3. Вы видели ссылку, которую я предоставил в своем ответе? Это официальный блог MySQL engineering. Если вам нужно что-то в руководстве по MySQL, вы можете искать это так же хорошо, как и я.
4. Я (и мой коллега) провели эффективный поиск в руководстве mysql, но мы ничего не нашли. Спасибо вам за ваше время и за ваш качественный ответ.
5. Я обнаружил это различие, тестируя модуль, который я написал, по сравнению с изображением MySQL 5.7 в конвейере. Локально, в контейнере MySQL 8, запрос
information_schema
таблицы приводит к тому, что объекты массива строк обладают именем свойстваTABLE_NAME
. Однако в MySQL 5.7 объект обладает свойством с именемtable_name
. Я просто тестирую как все верхние, так и все нижние значения в моем наборе результатов (if( (result?.[0]?.TABLE_NAME !== "x") amp;amp; (result?.[0]?.table_name !== "x") )
). Приятно знать, почему я должен. Хорошее объяснение — первое надежное подтверждение, которое я нашел. Быстро, с решениями тоже — спасибо!
Ответ №2:
Чувствительность к регистру не изменилась. Если вы проверите документацию mysql о чувствительности к регистру идентификаторов, в версиях 5.7 и 8.0 указано, что имена полей не чувствительны к регистру:
Имена столбцов, индексов, хранимых подпрограмм, событий и групп ресурсов не чувствительны к регистру ни на одной платформе, равно как и псевдонимы столбцов.
Мне это больше похоже на разницу в отображении.
Комментарии:
1. Как отмечает @Bill Karwin, изменение относится к набору строк результатов.
2. @Bruno эти изменения не имеют значения с точки зрения mysql, поскольку имена полей не чувствительны к регистру. В вопросе говорится только о mysql, ничего больше. Строго говоря, Билл ответил на другой вопрос, который указан только в удаленном ответе кем-то другим. Ответ на вопрос выше: чувствительность mysql к регистру не изменилась. Именно код вашего приложения чувствителен к регистру.
3. Я не согласен: он изменился унититивным образом, но он изменился: имена индексов набора строк результатов являются частью API mysql.
4. @Shadow, вы отвечаете на буквальный вопрос OP, но Бруно использовал терминологию неточно. Его проблема не в том, чувствителен ли MySQL к регистру . Его проблема в том, что изменился регистр столбцов в наборе результатов.
5. @BillKarwin тогда OP должен был обновить вопрос. В нынешнем виде ваш ответ не дает ответа на опубликованный вопрос. Это дает ответ на вопрос, подразумеваемый в удаленном ответе.