12.2.2 元数据的 UTF-8
元数据 是 "“关于数据的数据.”"。任何描述数据库—as opposed to 是数据库—的内容—is 元数据。因此,列名、数据库名、用户名、版本名和大多数来自SHOW
的字符串结果都是元数据。这也对INFORMATION_SCHEMA
表中的内容成立,因为这些表的定义包含关于数据库对象的信息。
元数据的表示必须满足以下要求:
为了满足这两个要求,MySQL 将元数据存储在 Unicode 字符集中,即 UTF-8。这对您不使用带点或非拉丁字母的字符没有影响。但是,如果您确实使用这些字符,您应该注意元数据是 UTF-8。
元数据要求意味着USER()
、CURRENT_USER()
、SESSION_USER()
、SYSTEM_USER()
、DATABASE()
和 VERSION()
函数的返回值默认使用 UTF-8 字符集。
服务器将character_set_system
系统变量设置为元数据字符集的名称:
Press CTRL+C to copymysql> SHOW VARIABLES LIKE 'character_set_system'; +----------------------+---------+ | Variable_name | Value | +----------------------+---------+ | character_set_system | utf8mb3 | +----------------------+---------+
使用 Unicode 存储元数据不意味着服务器默认返回列头和DESCRIBE
函数的结果在character_set_system
字符集中。当你使用 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 对你自动执行一些转换。
Press CTRL+C to copySELECT * FROM t1 WHERE USER() = latin1_column;
这是因为
latin1_column
的内容自动转换为 UTF-8 之前比较。
Press CTRL+C to copyINSERT INTO t1 (latin1_column) SELECT USER();
这是因为
USER()
的内容自动转换为latin1
之前赋值。
虽然自动转换不在 SQL 标准中,但是标准说每个字符集(在支持字符方面)都是 Unicode 的“子集”。因为是众所周知的原则“什么适用于 superset 也适用于 subset,”我们认为 Unicode 排序可以应用于非 Unicode 字符串比较。关于字符串强制转换的更多信息,请参见第12.8.4节,“表达式中的排序强制”。