文档首页
MySQL 9.0 参考手册
相关文档 下载本手册
PDF (US Ltr) - 40.0Mb
PDF (A4) - 40.1Mb
手册页 (TGZ) - 258.2Kb
手册页 (Zip) - 365.3Kb
Info (Gzip) - 4.0Mb
Info (Zip) - 4.0Mb


MySQL 9.0 参考手册  /  字符集、排序规则、Unicode  /  连接字符集和排序规则

12.4 连接字符集和排序规则

一个 连接 是客户端程序在连接到服务器时建立的,用于开始一个会话,在此会话中,客户端程序可以与服务器进行交互。客户端通过会话连接发送 SQL 语句,例如查询。服务器通过连接将响应(例如结果集或错误消息)发送回客户端。

连接字符集和排序规则系统变量

几个字符集和排序规则系统变量与客户端与服务器的交互相关。前面几节已经提到了其中的一些变量。

其他字符集和排序规则系统变量参与处理客户端与服务器之间的连接的流量。每个客户端都有与会话相关的连接字符集和排序规则系统变量。这些会话系统变量值在连接时初始化,但可以在会话中更改。

关于客户端连接的字符集和排序规则处理的几个问题可以通过系统变量来解答。

要查看应用于当前会话的字符集和排序规则系统变量的值,请使用以下语句。

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 设置为指定的字符集。

客户端程序连接字符集配置

当客户端连接到服务器时,它会指示它想要使用哪个字符集与服务器进行通信。(实际上,客户端指示该字符集的默认排序规则,服务器可以根据该排序规则确定字符集。)服务器使用此信息设置 character_set_clientcharacter_set_resultscharacter_set_connection 系统变量为字符集,并将 collation_connection 设置为字符集的默认排序规则。实际上,服务器执行相当于 SET NAMES 操作。

如果服务器不支持请求的字符集或排序规则,它将回退到使用服务器字符集和排序规则来配置连接。有关此回退行为的更多详细信息,请参阅 连接字符集错误处理

mysqlmysqladminmysqlcheckmysqlimportmysqlshow 客户端程序确定要使用的默认字符集的方式如下:

  • 在没有其他信息的情况下,每个客户端都使用编译后的默认字符集,通常为 utf8mb4

  • 每个客户端都可以根据操作系统设置自动检测要使用的字符集,例如 Unix 系统上的 LANGLC_ALL 本地环境变量的值,或 Windows 系统上的代码页设置。对于操作系统中提供本地化的系统,客户端使用它来设置默认字符集,而不是使用编译后的默认字符集。例如,将 LANG 设置为 ru_RU.KOI8-R 会导致使用 koi8r 字符集。因此,用户可以配置其环境中的本地化以便 MySQL 客户端使用。

    如果操作系统字符集没有完全匹配,则会映射到最接近的 MySQL 字符集。如果客户端不支持匹配的字符集,它将使用编译后的默认字符集。例如,utf8utf-8 映射到 utf8mb4,而 ucs2 不支持作为连接字符集,因此它映射到编译后的默认字符集。

    C 应用程序可以通过在连接到服务器之前调用 mysql_options() 来使用基于操作系统设置的字符集自动检测,如下所示

    mysql_options(mysql,
                  MYSQL_SET_CHARSET_NAME,
                  MYSQL_AUTODETECT_CHARSET_NAME);
  • 每个客户端都支持一个 --default-character-set 选项,它允许用户显式指定字符集以覆盖客户端否则确定的任何默认值。

    注意

    某些字符集不能用作客户端字符集。尝试使用它们与 --default-character-set 一起使用会导致错误。请参阅 不允许的客户端字符集

使用 mysql 客户端,要使用与默认字符集不同的字符集,您可以每次连接到服务器时显式执行 SET NAMES 语句(请参阅 客户端程序连接字符集配置)。为了更轻松地完成相同的结果,请在您的选项文件中指定字符集。例如,以下选项文件设置会更改每次调用 mysql 时设置的三个连接相关字符集系统变量为 koi8r

[mysql]
default-character-set=koi8r

如果您使用的是 mysql 客户端且启用了自动重新连接(不推荐),最好使用 charset 命令而不是 SET NAMES。例如

mysql> charset koi8r
Charset changed

charset 命令会发出 SET NAMES 语句,还会更改 mysql 在连接断开后重新连接时使用的默认字符集。

配置客户端程序时,您还必须考虑它们执行的环境。请参阅 第 12.5 节“配置应用程序字符集和排序规则”

用于连接字符集配置的 SQL 语句

建立连接后,客户端可以更改当前会话的字符集和排序规则系统变量。可以使用 SET 语句单独更改这些变量,但另外两个更方便的语句会将连接相关的字符集系统变量作为一组进行更改

注意

某些字符集不能用作客户端字符集。尝试使用它们与 SET NAMESSET CHARACTER SET 一起使用会导致错误。请参阅 不允许的客户端字符集

示例:假设 column1 定义为 CHAR(5) CHARACTER SET latin2。如果您没有说 SET NAMESSET CHARACTER SET,那么对于 SELECT column1 FROM t,服务器会使用客户端在连接时指定的字符集发送回 column1 的所有值。另一方面,如果您在发出 SELECT 语句之前说 SET NAMES 'latin1'SET CHARACTER SET 'latin1',服务器会在将结果发送回之前将 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/)

如果您指定了客户端识别但服务器无法识别的字符集,服务器会回退到其默认字符集和排序规则。假设服务器配置为使用 latin1latin1_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 |
+----------------------+-------------------+

您可以看到连接系统变量已被设置为反映 latin1latin1_swedish_ci 的字符集和排序规则。这是因为服务器无法满足客户端字符集请求,并回退到其默认值。

在这种情况下,客户端无法使用它想要的字符集,因为服务器不支持它。客户端必须要么愿意使用其他字符集,要么连接到支持所需字符集的其他服务器。

当客户端告诉服务器使用它识别的字符集时,也会出现相同的问题,但客户端侧该字符集的默认排序规则在服务器侧未知。

运行时错误处理

在已建立的连接中,客户端可以使用 SET NAMESSET 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;