文档首页
MySQL 9.0 参考手册
相关文档 下载本手册

12.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 | utf8mb3 |
+----------------------+---------+

使用 Unicode 存储元数据 意味着服务器默认以 character_set_system 字符集返回列的标题和 DESCRIBE 函数的结果。当您使用 SELECT column1 FROM t 时,column1 本身的名字将从服务器返回到客户端,使用的字符集由 character_set_results 系统变量的值决定,该变量的默认值为 utf8mb4。如果您希望服务器以其他字符集传递元数据结果,请使用 SET NAMES 语句强制服务器执行字符集转换。 SET NAMES 将设置 character_set_results 和其他相关的系统变量。(见 第 12.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 字符串的比较。有关字符串强制的更多信息,请参见 第 12.8.4 节,“表达式中的排序规则强制性”