10.2.2 UTF-8 для метаданных
Метаданные — это “данные о данных”. Все, что описывает базу данных, — в отличие от содержимого базы данных — это метаданные. Таким образом, имена столбцов, имена баз данных, имена пользователей, имена версий и большинство строковых результатов из SHOW являются метаданными. Это также относится к содержимому таблиц в INFORMATION_SCHEMA, поскольку эти таблицы по определению содержат информацию об объектах базы данных.
Представление метаданных должно удовлетворять следующим требованиям:
Все метаданные должны быть в одном кодировании символов. В противном случае ни операторы
SHOW, ни операторыSELECTдля таблиц вINFORMATION_SCHEMAне будут работать должным образом, потому что разные строки в одном столбце результатов этих операций будут в разных кодировках символов.Метаданные должны включать все символы всех языков. В противном случае пользователи не смогут называть столбцы и таблицы на своих языках.
Для удовлетворения обоих требований MySQL хранит метаданные в кодировке Unicode, а именно UTF-8. Это не вызывает никаких проблем, если вы никогда не используете акцентированные или нелатинские символы. Но если вы их используете, вы должны знать, что метаданные находятся в кодировке UTF-8.
Требования к метаданным означают, что возвращаемые значения функций USER(), CURRENT_USER(), SESSION_USER(), SYSTEM_USER(), DATABASE() и VERSION() по умолчанию имеют кодировку символов UTF-8.
Сервер устанавливает системную переменную character_set_system в имя кодировки символов метаданных:
mysql> SHOW VARIABLES LIKE 'character_set_system';
+----------------------+-------+
| Variable_name | Value |
+----------------------+-------+
| character_set_system | utf8 |
+----------------------+-------+
Хранение метаданных с помощью Unicode не означает, что сервер по умолчанию возвращает заголовки столбцов и результаты функций DESCRIBE в кодировке символов character_set_system. При использовании SELECT column1 FROM
t, имя column1 само по себе возвращается сервером клиенту в кодировке символов, определяемой значением системной переменной character_set_results, которая имеет значение по умолчанию utf8. Если вы хотите, чтобы сервер возвращал результаты метаданных в другой кодировке символов, используйте оператор SET
NAMES для принудительного выполнения преобразования кодировок символов. SET
NAMES устанавливает character_set_results и другие связанные системные переменные. (См. Раздел 10.4, «Настройки кодировки символов и сортировки соединения».) В качестве альтернативы программа-клиент может выполнить преобразование после получения результата от сервера. Для клиента более эффективно выполнить преобразование, но этот вариант не всегда доступен для всех клиентов.
Если character_set_results установлено в NULL, преобразование не выполняется, и сервер возвращает метаданные, используя исходную кодировку символов (кодировку, указанную в character_set_system).
Сообщения об ошибках, возвращаемые сервером клиенту, преобразуются в кодировку символов клиента автоматически, как и метаданные.
Если вы используете (например), функцию USER() для сравнения или присваивания в рамках одного оператора, не беспокойтесь. MySQL выполняет некоторые автоматические преобразования за вас.
SELECT * FROM t1 WHERE USER() = latin1_column;
Это работает, потому что содержимое latin1_column автоматически преобразуется в UTF-8 перед сравнением.
INSERT INTO t1 (latin1_column) SELECT USER();
Это работает, потому что содержимое функции USER() автоматически преобразуется в latin1 перед присваиванием.
Хотя автоматическое преобразование не соответствует стандарту SQL, стандарт гласит, что любая кодировка символов (с точки зрения поддерживаемых символов) является (“подмножеством”) Unicode. Поскольку это хорошо известный принцип, что (“то, что применяется к надмножеству, может применяться к подмножеству”), мы полагаем, что сортировка для Unicode может применяться для сравнений со строками, не являющимися Unicode. Более подробную информацию о принудительном преобразовании строк см. в Разделе 10.8.4, «Принудительное преобразование сортировки в выражениях».
© 2025 Oracle
Licensed under the GPLv2 License.