каковы изменения в наборе строк результатов mysql 8?

#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 должен был обновить вопрос. В нынешнем виде ваш ответ не дает ответа на опубликованный вопрос. Это дает ответ на вопрос, подразумеваемый в удаленном ответе.