10.4 Наборы символов и правила сопоставления соединений
«Соединение» — это то, что программа-клиент устанавливает при подключении к серверу, чтобы начать сеанс взаимодействия с сервером. Клиент отправляет SQL-запросы, такие как запросы, по соединению сеанса. Сервер отправляет ответы, такие как наборы результатов или сообщения об ошибках, по подключению обратно клиенту.
Системные переменные набора символов и правил сопоставления соединений
Несколько системных переменных набора символов и правил сопоставления связаны с взаимодействием клиента с сервером. Некоторые из них были упомянуты в предыдущих разделах:
Переменные
character_set_serverиcollation_serverуказывают на набор символов и правило сопоставления сервера. См. Раздел 10.3.2, «Набор символов и правило сопоставления сервера».Переменные
character_set_databaseиcollation_databaseуказывают на набор символов и правило сопоставления по умолчанию для базы данных. См. Раздел 10.3.3, «Набор символов и правило сопоставления базы данных».
Дополнительные системные переменные набора символов и правил сопоставления участвуют в обработке трафика для соединения между клиентом и сервером. Каждый клиент имеет свои системные переменные набора символов и правил сопоставления, специфичные для сеанса. Значения этих переменных сеанса инициализируются во время подключения, но могут быть изменены в рамках сеанса.
Некоторые вопросы о обработке наборов символов и правил сопоставления для подключений клиентов можно ответить в терминах системных переменных:
-
В каком наборе символов находятся инструкции, когда они покидают клиента?
Сервер принимает системную переменную
character_set_clientкак набор символов, в котором клиент отправляет инструкции.ПримечаниеНекоторые наборы символов не могут быть использованы в качестве набора символов клиента. См. Недопустимые наборы символов клиента.
-
В какой набор символов должен перевести сервер инструкции после их получения?
Для определения этого сервер использует переменные
character_set_connectionиcollation_connection:Сервер преобразует инструкции, отправленные клиентом, из
character_set_clientвcharacter_set_connection. Исключение: для строковых литералов, имеющих вводящий символ, например,_utf8mb4или_latin2, набор символов определяется вводящим символом. См. Раздел 10.3.8, «Вводящие символы набора символов».collation_connectionважен для сравнения строковых литералов. Для сравнения строк со значениями столбцовcollation_connectionне имеет значения, потому что столбцы имеют свои собственные правила сопоставления, которые имеют более высокий приоритет (см. Раздел 10.8.4, «Принуждение правил сопоставления в выражениях»).
-
В каком наборе символов сервер должен преобразовать результаты запроса перед отправкой обратно клиенту?
Переменная
character_set_resultsуказывает на набор символов, в котором сервер возвращает результаты запросов клиенту. Это включает данные результатов, такие как значения столбцов, метаданные результатов, такие как имена столбцов, и сообщения об ошибках.Чтобы указать серверу не выполнять преобразование наборов символов результатов или сообщений об ошибках, установите
character_set_resultsвNULLилиbinary:SET character_set_results = NULL; SET character_set_results = binary;
Дополнительную информацию о наборах символов и сообщениях об ошибках см. в Разделе 10.6, «Набор символов сообщений об ошибках».
Чтобы увидеть значения системных переменных набора символов и правил сопоставления, применяемых к текущему сеансу, используйте эту инструкцию:
SELECT * FROM performance_schema.session_variables
WHERE VARIABLE_NAME IN (
'character_set_client', 'character_set_connection',
'character_set_results', 'collation_connection'
) ORDER BY VARIABLE_NAME;
Следующие более простые инструкции также отображают переменные подключения, но включают и другие связанные переменные. Они могут быть полезны для просмотра всех системных переменных набора символов и правил сопоставления:
SHOW SESSION VARIABLES LIKE 'character\_set\_%';
SHOW SESSION VARIABLES LIKE 'collation\_%';
Клиенты могут настроить параметры этих переменных или полагаться на значения по умолчанию (в этом случае вы можете пропустить остальную часть этого раздела). Если вы не используете значения по умолчанию, вы должны изменить параметры набора символов для каждого подключения к серверу.
Недопустимые наборы символов клиента
Переменная character_set_client не может быть установлена на определенные наборы символов:
ucs2
utf16
utf16le
utf32
Попытка использовать любой из этих наборов символов в качестве набора символов клиента приводит к ошибке:
mysql> SET character_set_client = 'ucs2';
ERROR 1231 (42000): Variable 'character_set_client'
can't be set to the value of 'ucs2'
Такая же ошибка возникает, если любой из этих наборов символов используется в следующих контекстах, все из которых приводят к попытке установить character_set_client на указанный набор символов:
Опция командной строки
--default-character-set=, используемая MySQL-программами-клиентами, такими как mysql и mysqladmin.charset_nameИнструкция
SET NAMES '.charset_name'Инструкция
SET CHARACTER SET '.charset_name'
Настройка кодировки соединения клиентской программы
При подключении клиента к серверу он указывает кодировку, которую он хочет использовать для связи с сервером. (Фактически, клиент указывает значение по умолчанию для этой кодировки, по которому сервер может определить кодировку.) Сервер использует эту информацию для установки системных переменных character_set_client, character_set_results, character_set_connection на кодировку и collation_connection на значение по умолчанию для этой кодировки. По сути, сервер выполняет операцию, эквивалентную SET NAMES.
Если сервер не поддерживает запрошенную кодировку или сортировку, он использует кодировку и сортировку сервера для настройки соединения. Более подробную информацию об этом поведении обратного хода вы найдёте в разделе Обработка ошибок кодировки соединения.
Клиентские программы mysql, mysqladmin, mysqlcheck, mysqlimport и mysqlshow определяют кодировку по умолчанию следующим образом:
При отсутствии другой информации каждый клиент использует кодировку по умолчанию, скомпилированную в программу, обычно
latin1.-
Каждый клиент может автоматически определить используемую кодировку на основе настройки операционной системы, например, значения переменной среды локали
LANGилиLC_ALLна системах Unix или настроек кодовой страницы на системах Windows. Для систем, на которых локаль доступна из ОС, клиент использует её для установки кодировки по умолчанию вместо использования скомпилированной по умолчанию. Например, установкаLANGв значениеru_RU.KOI8-Rприводит к использованию кодировкиkoi8r. Таким образом, пользователи могут настроить локаль в своей среде для использования MySQL клиентами.Кодировка ОС сопоставляется с ближайшей кодировкой MySQL, если точного совпадения нет. Если клиент не поддерживает соответствующую кодировку, он использует кодировку по умолчанию, скомпилированную в программу. Например,
ucs2не поддерживается в качестве кодировки соединения, поэтому она сопоставляется со значением по умолчанию, скомпилированным в программу.Приложения C могут использовать автоматическое определение кодировки на основе настройки ОС, вызвав следующее перед подключением к серверу:
mysql_options(mysql, MYSQL_SET_CHARSET_NAME, MYSQL_AUTODETECT_CHARSET_NAME); -
Каждый клиент поддерживает опцию
--default-character-set, которая позволяет пользователям явно указать кодировку, чтобы переопределить любую кодировку по умолчанию, которую клиент определяет в ином случае.ПримечаниеНекоторые кодировки не могут использоваться в качестве кодировки клиента. Попытка использовать их с
--default-character-setприводит к ошибке. См. Недопустимые кодировки клиента.
В случае с клиентом mysql, чтобы использовать кодировку, отличную от кодировки по умолчанию, вы можете явно выполнить оператор SET NAMES каждый раз при подключении к серверу (см. Настройка кодировки соединения клиентской программы). Чтобы достичь того же результата проще, укажите кодировку в вашем файле параметров. Например, следующее значение в файле параметров изменяет три системных переменных кодировки, связанных с подключением, на koi8r каждый раз при вызове mysql:
[mysql]
default-character-set=koi8r
Если вы используете клиент mysql с включенной автоматической повторной установкой (что не рекомендуется), предпочтительнее использовать команду charset, а не SET NAMES. Например:
mysql> charset koi8r
Charset changed
Команда charset выполняет оператор SET NAMES и также изменяет кодировку по умолчанию, которую mysql использует при повторном подключении после разрыва соединения.
При настройке клиентских программ также необходимо учитывать среду, в которой они выполняются. См. Раздел 10.5, «Настройка кодировки и сортировки приложения».
SQL-запросы для настройки кодировки соединения
После установления соединения клиенты могут изменить переменные кодировки символов и правил сортировки для текущей сессии. Эти переменные можно изменить индивидуально, используя запросы SET, но существуют два более удобных запроса, влияющих на переменные кодировки, связанные с соединением, как группу:
-
SET NAMES 'charset_name' [COLLATE 'collation_name']SET NAMESуказывает кодировку символов, которую клиент использует для отправки SQL-запросов на сервер. Таким образом,SET NAMES 'cp1251'сообщает серверу, “будущие входящие сообщения от этого клиента используют кодировкуcp1251.” Он также задаёт кодировку символов, которую сервер должен использовать для отправки результатов обратно клиенту. (Например, он указывает кодировку, используемую для значений столбцов, если вы используете запросSELECT, который генерирует набор результатов.)Запрос
SET NAMES 'эквивалентен трём запросам:charset_name'SET character_set_client =
charset_name; SET character_set_results =charset_name; SET character_set_connection =charset_name;Установка
character_set_connectionвcharset_nameтакже неявно устанавливаетcollation_connectionна значение по умолчанию дляcharset_name. Явного задания этой сортировки не требуется. Чтобы указать конкретную сортировку дляcollation_connection, добавьте клаузуCOLLATE:SET NAMES '
charset_name' COLLATE 'collation_name' -
SET CHARACTER SET 'charset_nameSET CHARACTER SETпохож наSET NAMES, но устанавливаетcharacter_set_connectionиcollation_connectionнаcharacter_set_databaseиcollation_database(которые, как упоминалось ранее, указывают кодировку символов и сортировку по умолчанию для базы данных).Запрос
SET CHARACTER SETэквивалентен трём запросам:charset_nameSET character_set_client =
charset_name; SET character_set_results =charset_name; SET collation_connection = @@collation_database;Установка
collation_connectionтакже неявно устанавливаетcharacter_set_connectionна кодировку символов, связанную с сортировкой (эквивалентно выполнениюSET character_set_connection = @@character_set_database). Явного заданияcharacter_set_connectionне требуется.
Некоторые кодировки символов не могут использоваться в качестве кодировки клиента. Попытка использовать их с SET
NAMES или SET CHARACTER
SET приводит к ошибке. См. Недопустимые кодировки символов клиента.
Пример: Предположим, что column1 определён как CHAR(5) CHARACTER SET latin2. Если вы не укажете SET NAMES или SET CHARACTER SET, то для SELECT column1 FROM t сервер отправит все значения для column1, используя кодировку, указанную клиентом при подключении. С другой стороны, если вы укажете SET NAMES 'latin1' или SET CHARACTER SET 'latin1' перед выполнением запроса SELECT, сервер преобразует значения latin2 в latin1 непосредственно перед отправкой результатов. Преобразование может быть неполным для символов, которых нет в обеих кодировках.
Обработка ошибок кодировки соединения
Попытки использовать неподходящую кодировку соединения или сортировку могут привести к ошибке или заставить сервер перейти к своей кодировке и сортировке по умолчанию для данного соединения. В этом разделе описаны проблемы, которые могут возникнуть при настройке кодировки соединения. Эти проблемы могут возникнуть при установлении соединения или при изменении кодировки в рамках существующего соединения.
Обработка ошибок при подключении
Некоторые кодировки не могут быть использованы в качестве кодировки клиента; см. Недопустимые кодировки клиента. Если вы укажете кодировку, которая допустима, но не разрешена в качестве кодировки клиента, сервер вернёт ошибку:
$> mysql --default-character-set=ucs2
ERROR 1231 (42000): Variable 'character_set_client' can't be set to
the value of 'ucs2'
Если вы укажете кодировку, которую клиент не распознаёт, это вызовет ошибку:
$> mysql --default-character-set=bogus
mysql: Character set 'bogus' is not a compiled character set and is
not specified in the '/usr/local/mysql/share/charsets/Index.xml' file
ERROR 2019 (HY000): Can't initialize character set bogus
(path: /usr/local/mysql/share/charsets/)
Если вы укажете кодировку, которую клиент распознаёт, но сервер нет, сервер переходит к своей кодировке и сортировке по умолчанию. Предположим, что сервер настроен на использование latin1 и latin1_swedish_ci в качестве значений по умолчанию, и он не распознаёт gb18030 в качестве допустимой кодировки. Клиент, который указывает --default-character-set=gb18030, может подключиться к серверу, но результат — не та кодировка, которую хочет клиент:
mysql> SHOW SESSION VARIABLES LIKE 'character\_set\_%';
+--------------------------+--------+
| Variable_name | Value |
+--------------------------+--------+
| character_set_client | latin1 |
| character_set_connection | latin1 |
...
| character_set_results | latin1 |
...
+--------------------------+--------+
mysql> SHOW SESSION VARIABLES LIKE 'collation_connection';
+----------------------+-------------------+
| Variable_name | Value |
+----------------------+-------------------+
| collation_connection | latin1_swedish_ci |
+----------------------+-------------------+
Вы можете увидеть, что переменные системы соединения были установлены для отражения кодировки и сортировки latin1 и latin1_swedish_ci. Это происходит потому, что сервер не может удовлетворить запрос клиента на кодировку и переходит к значениям по умолчанию.
В этом случае клиент не может использовать желаемую кодировку, поскольку сервер её не поддерживает. Клиент должен либо принять другую кодировку, либо подключиться к другому серверу, поддерживающему нужную кодировку.
Такая же проблема возникает в более тонком контексте: когда клиент сообщает серверу использовать кодировку, которую сервер распознаёт, но сортировка по умолчанию для этой кодировки на стороне клиента неизвестна на стороне сервера. Например, это происходит, когда клиент MySQL 8.0 хочет подключиться к серверу MySQL 5.7, используя utf8mb4 в качестве кодировки клиента. Клиент, который указывает --default-character-set=utf8mb4, может подключиться к серверу. Однако, как и в предыдущем примере, сервер переходит к своей кодировке и сортировке по умолчанию, а не к той, которую запросил клиент:
mysql> SHOW SESSION VARIABLES LIKE 'character\_set\_%';
+--------------------------+--------+
| Variable_name | Value |
+--------------------------+--------+
| character_set_client | latin1 |
| character_set_connection | latin1 |
...
| character_set_results | latin1 |
...
+--------------------------+--------+
mysql> SHOW SESSION VARIABLES LIKE 'collation_connection';
+----------------------+-------------------+
| Variable_name | Value |
+----------------------+-------------------+
| collation_connection | latin1_swedish_ci |
+----------------------+-------------------+
Почему это происходит? Ведь utf8mb4 известна как клиенту 8.0, так и серверу 5.7, поэтому оба её распознают. Чтобы понять это поведение, необходимо понять, что когда клиент сообщает серверу, какую кодировку он хочет использовать, он фактически сообщает серверу сортировку по умолчанию для этой кодировки. Таким образом, указанное поведение обусловлено совокупностью факторов:
Сортировка по умолчанию для
utf8mb4отличается между MySQL 5.7 и 8.0 (utf8mb4_general_ciдля 5.7,utf8mb4_0900_ai_ciдля 8.0).Когда клиент 8.0 запрашивает кодировку
utf8mb4, он отправляет серверу сортировку по умолчанию 8.0utf8mb4; то естьutf8mb4_0900_ai_ci.utf8mb4_0900_ai_ciреализована только начиная с MySQL 8.0, поэтому сервер 5.7 её не распознаёт.Поскольку сервер 5.7 не распознаёт
utf8mb4_0900_ai_ci, он не может удовлетворить запрос клиента на кодировку и переходит к своей кодировке и сортировке по умолчанию (latin1иlatin1_swedish_ci).
В этом случае клиент по-прежнему может использовать utf8mb4, выполнив оператор SET NAMES
'utf8mb4' после подключения. Результатом будет сортировка по умолчанию 5.7 — utf8mb4; то есть utf8mb4_general_ci. Если клиент также хочет сортировку utf8mb4_0900_ai_ci, он не сможет этого достичь, поскольку сервер не распознаёт эту сортировку. Клиент должен либо принять другую сортировку utf8mb4, либо подключиться к серверу MySQL 8.0 или выше.
Обработка ошибок во время выполнения
В рамках установленного соединения клиент может запросить изменение кодировки и сортировки соединения с помощью SET NAMES или SET CHARACTER SET.
Некоторые кодировки не могут быть использованы в качестве кодировки клиента; см. Недопустимые кодировки клиента. Если вы укажете кодировку, которая допустима, но не разрешена в качестве кодировки клиента, сервер вернёт ошибку:
mysql> SET NAMES 'ucs2';
ERROR 1231 (42000): Variable 'character_set_client' can't be set to
the value of 'ucs2'
Если сервер не распознаёт кодировку (или сортировку), он выдаст ошибку:
mysql> SET NAMES 'bogus';
ERROR 1115 (42000): Unknown character set: 'bogus'
mysql> SET NAMES 'utf8mb4' COLLATE 'bogus';
ERROR 1273 (HY000): Unknown collation: 'bogus'
Клиент, желающий проверить, была ли запрошенная им кодировка принята сервером, может выполнить следующую команду после подключения и проверить, что результат соответствует ожидаемой кодировке:
SELECT @@character_set_client;
© 2025 Oracle
Licensed under the GPLv2 License.