MySQL 设置 UTF-8
遇到了一些问题?
为什么要设置?
TL;DR:生产环境中如果用
utf8
而不是utf8mb4
会导致数据丢失。
MySQL 的开发者自作多情,它的默认 utf8
字符集对于每个字符只支持最多 3 个字节,而真正的 UTF-8(即 2010 年发布了一个叫作 utf8mb4
的字符集) 是每个字符最多 4 个字节。这使得像「💩」(U+01F4A9)这种 emoji 和「𝌆」(U+1D306)这种符号都无法被插入,你会得到一个错误编号为 1366 的 Warning:
Incorrect string value: '\xF0\x9D\x8C\x86' for column 'column_name' at row 1
而就是这一个字节的差距,导致 MySQL 原本的 utf8
只能让你存储 5.88% 的所有 Unicode 字符。正常的 utf8mb4
则是 100%。
如何修改?
如果你是新安装的,那么从第 5 步看起。
1. 首先,备份你的数据库以防不测。
2. 然后,升级你的 MySQL 至 v5.5.3+。
3. 接着,将表从 utf8
更换成 utf8mb4
:
# 对于每个数据库
ALTER DATABASE database_name CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci;
# 对于每个表
ALTER TABLE table_name CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
# 对于每项
ALTER TABLE table_name CHANGE column_name column_name VARCHAR(191) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
# 不要盲目复制粘贴这些,这些只是例子!!
4. 检查列和索引键的最大长度
这可能是最难的,因为我们的字符从 3 字节变成了 4 字节。
如果不知道怎么办,可以看看官方文档。
5. 找到你的 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
然后用这个命令看看它工作吗?
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 |
+--------------------------+--------------------+
6. 修复与优化
可以进每个表这样:
REPAIR TABLE table_name;
OPTIMIZE TABLE table_name;
或者一次性解决:
mysqlcheck -u 用户名 -p --auto-repair --optimize --all-databases
utf8mb4_unicode_ci
还是 utf8mb4_general_ci
?
utf8mb4_unicode_ci
是完完整整按照 Unicode 设计的。
utf8mb4_general_ci
是为了速度上的优化而「偷懒」的,当然也不完完全全遵守 Unicode。
一般来说,除非真的运行在慢机子上,否则还是用前者为好。
参考文献
- https://www.infoq.cn/article/in-mysql-never-use-utf8-use-utf8
- https://mathiasbynens.be/notes/mysql-utf8mb4
- https://stackoverflow.com/questions/766809/whats-the-difference-between-utf8-general-ci-and-utf8-unicode-ci
如果喜欢本文,欢迎点击下方的「鼓掌」按钮!
如果上面没有加载出任何东西,可以点击这里。
如果喜欢本文,欢迎点击下方的「鼓掌」按钮!
如果上面没有加载出任何东西,可以点击这里。