向 MySQL 更新数据时若遇到:
Incorrect string value: '\xF0\x9F\x98\x82\xEF\xBC...' for column 'content' at row 1
通常是因为字段字符集为 utf8
,无法存储 emoji 表情,需要改为 utf8mb4
。
utf8 与 utf8mb4 的差别
- MySQL 的
utf8
最多支持 3 字节编码,不是完整的 UTF-8。 utf8mb4
才能覆盖所有 Unicode 字符,包括 emoji。- 建议 MySQL 或 MariaDB 用户统一使用
utf8mb4
。
配置 utf8mb4
全局配置
若可修改数据库服务器配置,更新 MySQL 配置文件:
[client]
default-character-set = utf8mb4
[mysql]
default-character-set = utf8mb4
[mysqld]
# 忽略客户端的字符集请求,强制使用服务器字符集返回结果
character-set-client-handshake = FALSE
character-set-server = utf8mb4
collation-server = utf8mb4_unicode_ci
检查结果:
mysql> SHOW VARIABLES WHERE Variable_name LIKE 'character\_set\_%' OR Variable_name LIKE 'collation%';
+--------------------------+--------------------+
| 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 |
| collation_connection | utf8mb4_unicode_ci |
| collation_database | utf8mb4_unicode_ci |
| collation_server | utf8mb4_unicode_ci |
+--------------------------+--------------------+
10 rows in set (0.00 sec)
单库配置
如无法调整服务器设置,可在数据库层指定:
- 创建数据库时:
CREATE DATABASE dbname CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci;
- 连接数据库时在连接串指定字符集:
mysql+[driver]://[username]:[password]@[host]:[port]/[dbname]?charset=utf8mb4
从 utf8 迁移至 utf8mb4
- 备份数据;
- 确认 MySQL 版本 ≥ 5.5.3;
- 修改数据库、表、字段字符集:
# 数据库
ALTER DATABASE database_name CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci;
# 表
ALTER TABLE table_name CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
# varchar 字段
ALTER TABLE table_name CHANGE column_name column_name VARCHAR(xx) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
- 检查索引长度是否超限,参考官方文档;
- 配置服务器字符集(见前文);
- 修复并优化表:
REPAIR TABLE table_name;
OPTIMIZE TABLE table_name;
或使用:
mysqlcheck -u root -p --auto-repair --optimize --all-databases