MySQL字符集设置,utf8和utf8mb4区别
前言
存个emoji表情,MySQL报错" Incorrect string value",乱码了。这就是字符集没设对。
一、utf8和utf8mb4区别
| 字符集 | 最多字节 | 支持表情 | 说明 |
|---|---|---|---|
| utf8 | 3字节 | 不支持 | 只能存BMP字符 |
| utf8mb4 | 4字节 | 支持 | 完整UTF-8 |
注意: MySQL的utf8是阉割版,真正的UTF-8是utf8mb4。
为什么要用utf8mb4
存emoji表情(😀🍔🚀),utf8存不了,会报错。
ERROR 1366 (HY000): Incorrect string value: '\xF0\x9F\x98\x80' for column 'content'
二、查看当前字符集
SHOW VARIABLES LIKE 'character_set%';
输出:
| Variable_name | Value |
|---|---|
| character_set_server | utf8mb4 |
| character_set_database | utf8 |
| character_set_client | utf8 |
三、设置字符集
1. 改my.cnf
[mysqld]
# 服务器字符集
character-set-server = utf8mb4
collation-server = utf8mb4_general_ci
[client]
default-character-set = utf8mb4
[mysql]
default-character-set = utf8mb4
重启MySQL:
systemctl restart mysqld
2. 建库时指定
CREATE DATABASE mydb
DEFAULT CHARACTER SET utf8mb4
COLLATE utf8mb4_general_ci;
3. 建表时指定
CREATE TABLE users (
id INT PRIMARY KEY,
name VARCHAR(50)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
4. 改已有库字符集
ALTER DATABASE mydb CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
5. 改已有表字符集
ALTER TABLE users CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
四、连接字符集
连接时也要设对,不然还是乱码。
PHP连接时设置
mysqli_set_charset($conn, 'utf8mb4');
连接后执行SQL
SET NAMES utf8mb4;
五、collation排序规则
| 规则 | 说明 |
|---|---|
| utf8mb4_general_ci | 不区分大小写,快 |
| utf8mb4_unicode_ci | 不区分大小写,准 |
| utf8mb4_bin | 区分大小写,二进制 |
推荐用utf8mb4_general_ci,快。
六、常见问题
问题1:存emoji报错
原因: 字段是utf8不是utf8mb4。
解决: 改成utf8mb4。
问题2:中文乱码
原因: 连接字符集不对。
解决: 连接后执行 SET NAMES utf8mb4。
问题3:like查询不区分大小写
原因: 用了_ci结尾的排序规则。
解决: 改用_bin。
常见坑
坑1:只改了表,没改库
库是latin1,表是utf8mb4,导数据还是乱码。
解决: 库、表、连接都要统一字符集。
坑2:改了表字符集,数据还是乱
改了表,但旧数据已经存成latin1了。
解决: 需要转码:
ALTER TABLE t MODIFY c BLOB;
ALTER TABLE t MODIFY c TEXT CHARACTER SET utf8mb4;
坑3:utf8和utf8mb4混用
有的表utf8,有的表utf8mb4,联表查询报错。
解决: 全库统一用utf8mb4。
坑4:mysqlclient不支持utf8mb4
老版本客户端不支持utf8mb4。
解决: 升级MySQL客户端。
总结
记住三点:
- 数据库、表、连接全部用utf8mb4
- 排序规则用utf8mb4_general_ci
- 存emoji必须用utf8mb4
别用utf8了,直接上utf8mb4。
遇到问题加QQ23979811 协助处理