### 10.2.2元数据的UTF-8

[](<>)[](<>)[](<>)

元数据是“关于数据的数据”任何*描写*数据库，而不是*目录*数据库的核心是元数据。因此，列名、数据库名、用户名、版本名和大多数字符串都是由[`显示`](show.html)是元数据。中表格的内容也是如此`信息模式`因为根据定义，这些表包含有关数据库对象的信息。

元数据的表示必须满足以下要求：

-   所有元数据必须在同一字符集中。否则，无论是[`显示`](show.html)声明或[`选择`](select.html)中的表的语句`信息模式`将正常工作，因为这些操作结果的同一列中的不同行将位于不同的字符集中。

-   元数据必须包含所有语言中的所有字符。否则，用户将无法使用自己的语言命名列和表。

    为了满足这两个要求，MySQL以Unicode字符集（即UTF-8）存储元数据。如果从不使用重音或非拉丁字符，这不会造成任何中断。但如果你这么做了，你应该知道元数据是在UTF-8中。

    元数据要求意味着[`用户（）`](information-functions.html#function_user),[`当前用户（）`](information-functions.html#function_current-user),[`会话_用户（）`](information-functions.html#function_session-user),[`系统_用户（）`](information-functions.html#function_system-user), [`数据库（）`](information-functions.html#function_database)和[`版本（）`](information-functions.html#function_version)默认情况下，函数具有UTF-8字符集。

    服务器设置[`字符集系统`](server-system-variables.html#sysvar_character_set_system)元数据字符集名称的系统变量：


```
mysql> SHOW VARIABLES LIKE 'character_set_system';
+----------------------+-------+
| Variable_name        | Value |
+----------------------+-------+
| character_set_system | utf8  |
+----------------------+-------+
```

使用Unicode存储元数据*不*这意味着服务器返回列的标题和[`描述`](describe.html)中的功能[`字符集系统`](server-system-variables.html#sysvar_character_set_system)默认设置为字符集。当你使用`从t中选择column1`，名字`专栏1`它本身从服务器返回到客户机，返回的字符集由[`字符集结果`](server-system-variables.html#sysvar_character_set_results)系统变量，其默认值为`utf8mb4`。如果希望服务器以不同的字符集传回元数据结果，请使用[`定名`](set-names.html)语句强制服务器执行字符集转换。[`定名`](set-names.html)设定[`字符集结果`](server-system-variables.html#sysvar_character_set_results)以及其他相关的系统变量。（见[第10.4节，“连接字符集和排序规则”](charset-connection.html)）或者，客户端程序可以在从服务器接收结果后执行转换。客户机执行转换的效率更高，但并非所有客户机都可以使用此选项。

如果[`字符集结果`](server-system-variables.html#sysvar_character_set_results)即将`无效的`，则不执行任何转换，服务器使用其原始字符集（由[`字符集系统`](server-system-variables.html#sysvar_character_set_system)).

与元数据一样，从服务器返回到客户端的错误消息会自动转换为客户端字符集。

如果您正在使用（例如）[`用户（）`](information-functions.html#function_user)函数用于在单个语句中进行比较或赋值，不用担心。MySQL为您执行一些自动转换。

```
SELECT * FROM t1 WHERE USER() = latin1_column;
```

这是因为`拉丁1_列`在比较之前自动转换为UTF-8。

```
INSERT INTO t1 (latin1_column) SELECT USER();
```

这是因为[`用户（）`](information-functions.html#function_user)自动转换为`拉丁语1`在作业之前。

尽管SQL标准中没有自动转换，但该标准确实规定每个字符集（就支持的字符而言）都是Unicode的“子集”。因为“适用于超集的内容可以适用于子集”这一众所周知的原则，我们相信Unicode的排序规则可以适用于与非Unicode字符串的比较。有关强制字符串的更多信息，请参阅[第10.8.4节，“表达式中的排序强制性”](charset-collation-coercibility.html).
