---
url: /doc/Databases/ufrh60og/index.md
---
> 著作权归 JavaGuide(javaguide.cn)所有 基于 MIT 协议 原文链接：https://javaguide.cn/database/character-set.html

### Cue

* 字符集和字符编码的区别？
* MySQL 中 `utf8` 和 `utf8mb4` 的区别？
* 如何解决 MySQL 存储 emoji 符号的问题？
* 常见字符集（ASCII、GB2312、GBK、GB18030、Unicode）的特点？
* MySQL 字符集的层次级别有哪些？
* 如何查看和设置 MySQL 的默认字符集？
* 连接字符集的作用和设置方法？
* JDBC 对连接字符集的影响？

### Main

#### 字符集与字符编码

* **字符集**：一系列字符的集合，如 ASCII、GB2312、Unicode。
* **字符编码**：将字符集中的字符与二进制数据相互转换的规则，如 UTF-8、GBK。

#### 常见字符集

* **ASCII**：主要用于现代美国英语，共 128 个字符，扩展版有 256 个字符。
* **GB2312**：支持汉字，共 6700 多个汉字，不支持生僻字和繁体字。
* **GBK**：GB2312 的扩展，共 20000 多个汉字。
* **GB18030**：最全面的汉字字符集，共 70000 多个汉字。
* **Unicode**：包含世界上几乎所有已知字符，UTF-8 是其一种编码方式。

#### MySQL 字符集

* **`utf8`**：MySQL 的 UTF-8 实现，只支持 1-3 字节，无法存储 emoji 符号。

* **`utf8mb4`**：完整的 UTF-8 实现，支持 1-4 字节，可存储 emoji 符号。

* **层次级别**：

  * `server`：MySQL 实例级别，默认值在 MySQL 5.7 是 `latin1`，MySQL 8.0 是 `utf8mb4`。
  * `database`：数据库级别，创建数据库时指定。
  * `table`：表级别，创建表时指定。
  * `column`：字段级别，创建表时指定。

* **查看默认字符集**：

  ```sql
  SHOW VARIABLES LIKE 'character_set_server';
  ```

* **设置默认字符集**：
  ```sql
  SET character_set_server = utf8mb4;
  ```

#### 连接字符集

* **`character_set_client`**：客户端发送 SQL 语句的字符集。
* **`character_set_connection`**：服务器接收 SQL 语句时的字符集。
* **`character_set_results`**：服务器返回结果的字符集。
* **设置方法**：
  ```sql
  SET NAMES utf8mb4;
  ```

#### JDBC 对连接字符集的影响

* JDBC 驱动通过 `characterEncoding` 和 `characterSetResults` 属性影响连接字符集。
* 低版本的 JDBC 驱动可能不支持 `utf8mb4`，导致 emoji 符号显示为问号。

#### 示例

* 使用 `utf8` 编码存储 emoji 符号会报错：
  ```sql
  CREATE TABLE `user` (
    `id` varchar(66) CHARACTER SET utf8 NOT NULL,
    `name` varchar(33) CHARACTER SET utf8 NOT NULL
  ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
  INSERT INTO `user` (`id`, `name`) VALUES ('A00003', 'guide哥😘');
  ```
  报错信息：`Incorrect string value: '\xF0\x9F\x98\x98...' for column 'name' at row 1`

### Summary

本文详细介绍了字符集和字符编码的基本概念，重点分析了 MySQL 中 `utf8` 和 `utf8mb4` 的区别，并通过示例说明了如何解决 MySQL 存储 emoji 符号的问题。同时，还介绍了 MySQL 字符集的层次级别、连接字符集的作用以及 JDBC 对连接字符集的影响。
