MySQL字符集设置,utf8和utf8mb4区别

前言

做网站开发的同学肯定都遇到过中文乱码的问题。本来好好的中文,存到数据库里就变成问号或者乱码了。这其实很大概率就是字符集设置不对导致的。

很多新手同学不知道utf8和utf8mb4有什么区别,建库的时候直接用默认的utf8,结果存个emoji表情就报错了,或者存进去之后变成乱码。

这篇文章就详细讲讲MySQL字符集的设置方法,以及utf8和utf8mb4到底有什么区别,应该怎么选。

一、utf8和utf8mb4的区别

首先大家要搞清楚一个坑:MySQL里的utf8并不是真正的UTF-8。

MySQL里的utf8字符集,每个字符最多只能存3个字节。而真正的UTF-8编码,有些字符是占4个字节的,比如emoji表情(😀😂👍这些),还有一些生僻字。

所以如果你用utf8字符集,存emoji表情的时候就会报错,或者存进去之后变成乱码。

而utf8mb4才是真正的UTF-8,每个字符最多可以存4个字节,emoji表情、生僻字都能正常存。

总结一下:

  • utf8:每个字符最多3字节,存不了emoji表情
  • utf8mb4:每个字符最多4字节,完全兼容UTF-8,推荐使用

现在做新项目,直接用utf8mb4就对了,不要再用utf8了。

二、查看当前MySQL字符集设置

先看看你的MySQL现在用的是什么字符集:

SHOW VARIABLES LIKE '%character%';

执行完之后会看到类似下面的输出:

+--------------------------+----------------------------+
| Variable_name            | Value                      |
+--------------------------+----------------------------+
| character_set_client     | utf8mb4                    |
| character_set_connection | utf8mb4                    |
| character_set_database   | utf8mb4                    |
| character_set_filesystem | binary                     |
| character_set_results    | utf8mb4                    |
| character_set_server     | utf8mb4                    |
| character_set_system     | utf8                       |
| character_sets_dir       | /usr/share/mysql/charsets/ |
+--------------------------+----------------------------+

重点看这几个:

  • character_set_server:服务器默认字符集
  • character_set_database:当前数据库的字符集
  • character_set_client:客户端字符集
  • character_set_connection:连接字符集
  • character_set_results:查询结果字符集

最好这几个都统一成utf8mb4,这样就不会有乱码问题了。

三、新建数据库的时候指定utf8mb4

如果你要新建一个数据库,直接在建库的时候指定字符集:

CREATE DATABASE testdb 
DEFAULT CHARACTER SET utf8mb4 
COLLATE utf8mb4_general_ci;

这样建出来的数据库默认就是utf8mb4字符集了。

新建表的时候也可以指定:

CREATE TABLE users (
    id INT PRIMARY KEY AUTO_INCREMENT,
    name VARCHAR(50)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

四、修改MySQL默认字符集

如果你想把MySQL的默认字符集改成utf8mb4,可以修改my.cnf配置文件。

找到MySQL的配置文件 /etc/my.cnf,在 [mysqld] 下面添加:

[mysqld]
character-set-server=utf8mb4
collation-server=utf8mb4_general_ci

[client]
default-character-set=utf8mb4

[mysql]
default-character-set=utf8mb4

修改完之后重启MySQL服务:

systemctl restart mysqld

这样以后新建的数据库和表就默认都是utf8mb4字符集了。

五、修改已有数据库的字符集

如果你的数据库已经建好了,想改成utf8mb4,可以执行:

ALTER DATABASE testdb 
CHARACTER SET utf8mb4 
COLLATE utf8mb4_general_ci;

注意:这个只会修改数据库的默认字符集,已经建好的表的字符集不会变。

六、修改已有表的字符集

如果要修改某一张表的字符集,可以执行:

ALTER TABLE users 
CONVERT TO CHARACTER SET utf8mb4 
COLLATE utf8mb4_general_ci;

这样整张表的所有字段都会改成utf8mb4字符集。

如果要批量修改整个数据库里所有表的字符集,可以生成一个SQL脚本:

SELECT CONCAT('ALTER TABLE ', table_name, ' CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;')
FROM information_schema.tables
WHERE table_schema = 'testdb';

执行完之后会生成一堆ALTER TABLE语句,把这些语句复制出来执行就行。

七、连接的时候指定字符集

除了数据库和表的字符集,连接的时候也要指定字符集,不然还是可能会乱码。

用命令行连接的时候:

mysql -u root -p --default-character-set=utf8mb4

或者登录之后执行:

SET NAMES utf8mb4;

常见坑

坑1:用了utf8字符集,存emoji表情报错

很多同学建库的时候用的是utf8,结果存个emoji表情就报错了,或者存进去之后变成问号。这就是因为utf8最多只能存3个字节,emoji表情是4个字节的。

解决方法就是把字符集改成utf8mb4。

坑2:数据库字符集改了,但是表的字符集没改

很多同学改完数据库的字符集之后,以为就完事了,结果还是乱码。这是因为数据库的默认字符集改了,但是已经建好的表的字符集还是旧的。

一定要把表的字符集也一起改了,最好是整张表转成utf8mb4。

坑3:连接字符集不对,导致中文乱码

有时候数据库和表都是utf8mb4,但是查出来还是乱码。这一般是连接字符集不对。可以执行 SET NAMES utf8mb4 试一下,或者连接的时候加上 --default-character-set=utf8mb4 参数。

坑4:utf8mb4_general_ci和utf8mb4_unicode_ci选哪个

很多同学不知道这两个排序规则有什么区别。简单来说:

  • utf8mb4_general_ci:速度快,但是对一些特殊字符的排序可能不太准确
  • utf8mb4_unicode_ci:排序更准确,但是速度稍微慢一点

一般网站用utf8mb4_general_ci就够了,不用太纠结。

总结

MySQL字符集和utf8mb4的核心知识点:

  1. MySQL的utf8不是真正的UTF-8,最多只能存3字节
  2. utf8mb4才是真正的UTF-8,能存emoji表情,推荐使用
  3. 新建数据库和表的时候直接用utf8mb4
  4. 老的数据库如果要改,要同时改数据库和表的字符集
  5. 连接的时候也要指定utf8mb4,不然还是会乱码

现在做新项目,直接全程用utf8mb4就对了,省得以后再改。

遇到问题加QQ23979811 协助处理


emer 发布于  2026-10-5 08:43