想讲讲MySQL字符集的事

MySQL是当今最流行的关系型数据库之一,其性能高、可靠性好、成本低,广泛应用于互联网上的各类中小型网站及开发项目。但也我相信绝大多数使用MySQL的中文开发者都被MySQL的默认字符集坑过,MySQL易于上手,但是其默认设置对中文的支持并不好,让很多初学者很是头疼

如果没有更改MySQL的配置,那么我们在向数据库中插入中文字符串的时候很可能出现1366, "Incorrect string value"这一错误,它出现的原因在于要插入的字符串和数据库当前的字符集并不匹配。那么MySQL的默认字符集是什么?可以在数据库内使用show variables like '%char%';这一指令来查看,结果如下图。

可以看到character_set_databasecharacter_set_server字段的值都为latin1,那么latin1又是什么,和我们常见的utf8又有什么区别?以下摘自是维基百科。

ISO 8859-1,正式编号为ISO/IEC 8859-1:1998,又称Latin-1或“西欧语言”,是国际标准化组织ISO/IEC 8859的第一个8位字符集。它以ASCII为基础,在空置的0xA0-0xFF的范围内,加入96个字母符号,藉以供使用附加符号拉丁字母语言使用。曾推出过 ISO 8859-1:1987 版。

与ISO/IEC 10646即Unicode的关系:ISO-8859-1对应于ISO/IEC 10646即Unicode的前256个码位。

至此就可以理解插入中文字符报错的原因了,解决方案有三:

一、更改库的默认字符集

创建库的时候指定默认字符集

create database databasename default charset=utf8;

或者修改已有库的字符集

alter database databasename character set utf8;

二、更改表的默认字符集

在创建表的时候指定默认字符集

create table tablename (...) default charset=utf8;

或者修改已有表的字符集

alter table tablename character set utf8;

三、修改配置文件

# 进入到mysql配置文件所在路径:
cd /etc/mysql/mysql.conf.d/ 
# 备份(-p选项会把原文件的权限也一起复制)
cp -p mysql.cnf mysql.cnf.bak
#用vi打开配置文件mysqld.cnf并进行修改
vi mysqld.cnf
#找到 [mysqld],在 tmpdir =/tmp 后面按o键换行插入
character_set_server=utf8
#按esc键 退出插入模式,按shift + : 进入命令行,输入wq保存并退出
#重启mysql服务
/etc/init.d/mysql restart

如此以来我们就成功修改了MySQL的字符集,可以愉快地插入中文字符。

但是事情并没有那么简单!实际上现在我们使用的这个utf8字符集并不是完全体,MySQL中的“utf8”实际上只支持每个字符最多三个字节,而真正的UTF-8是每个字符支持最多四个字节!在大多数情况下这个伪utf8并不会造成太多问题,但是当你想要插入一些MySQL开发者认为的生僻字符,比如emoji标签,你会惊讶地发现上面的1366错误又双叒叕出现了。

当然,MySQL开发者们认识到了这个问题,虽然他们没有声张,他们在2010年发布了一个叫作“utf8mb4”的字符集,虽然他们没有声张,而这个字符集才是真正的“UTF-8”,虽然他们没有声张。

所有使用MySQL的用户都应该改用“utf8mb4”,不要再使用“utf8”!否则当你遇到类似的问题时你会觉得被MySQL愚弄的自己像个傻子。。。

所以当我们在使用上面的方法来解决1366错误时,一定要把其中utf8改成utf8mb4!

参考链接:

https://blog.csdn.net/weixin_43023004/article/details/81942362

https://zh.wikipedia.org/wiki/ISO/IEC_8859-1

https://www.infoq.cn/article/in-mysql-never-use-utf8-use-utf8

Leave a Reply

Your email address will not be published. Required fields are marked *