MySQL是当今最流行的关系型数据库之一,其性能高、可靠性好、成本低,广泛应用于互联网上的各类中小型网站及开发项目。但也我相信绝大多数使用MySQL的中文开发者都被MySQL的默认字符集坑过,MySQL易于上手,但是其默认设置对中文的支持并不好,让很多初学者很是头疼
如果没有更改MySQL的配置,那么我们在向数据库中插入中文字符串的时候很可能出现1366, "Incorrect string value"
这一错误,它出现的原因在于要插入的字符串和数据库当前的字符集并不匹配。那么MySQL的默认字符集是什么?可以在数据库内使用show variables like '%char%';
这一指令来查看,结果如下图。

可以看到character_set_database
和character_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