Spec-Zone.ru › MySQL 5.7

10.4 Наборы символов и правила сопоставления соединений

«Соединение» — это то, что программа-клиент устанавливает при подключении к серверу, чтобы начать сеанс взаимодействия с сервером. Клиент отправляет SQL-запросы, такие как запросы, по соединению сеанса. Сервер отправляет ответы, такие как наборы результатов или сообщения об ошибках, по подключению обратно клиенту.

  • Системные переменные набора символов и правил сопоставления соединений

  • Недопустимые наборы символов клиента

  • Настройка набора символов подключения программы-клиента

  • 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=charset_name, используемая MySQL-программами-клиентами, такими как mysql и mysqladmin.

  • Инструкция SET NAMES 'charset_name'.

  • Инструкция SET CHARACTER SET 'charset_name'.

END_OF_DOCUMENT_MARKER ```

Настройка кодировки соединения клиентской программы

При подключении клиента к серверу он указывает кодировку, которую он хочет использовать для связи с сервером. (Фактически, клиент указывает значение по умолчанию для этой кодировки, по которому сервер может определить кодировку.) Сервер использует эту информацию для установки системных переменных 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_name

    SET CHARACTER SET похож на SET NAMES, но устанавливает character_set_connection и collation_connection на character_set_database и collation_database (которые, как упоминалось ранее, указывают кодировку символов и сортировку по умолчанию для базы данных).

    Запрос SET CHARACTER SET charset_name эквивалентен трём запросам:

    SET 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.0 utf8mb4; то есть 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.
https://docs.oracle.com/cd/E17952_01/mysql-5.7-en/charset-connection.html

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API