创建数据库的时候没注意编码问题,在插入富文本字符串的时候发现数据库会报错,这里简要说明一下。
提示信息
SQL Error: 1366, SQLState: HY000
Incorrect string value: '\xF0\x9F\x91\x87\xEF\xB8...' for column 'xx字段' at row 1
明显可以知道是数据库的编码字段异常导致。
问题原因
数据库某字段设置的是utf8字符集,在执行插入或修改语句时该字段传入的值是非utf8格式(表情或特殊字符)的内容就会出现上面的提示信息。
我们都知道MySQL的utf8只支持最大3字节每字符,已经包含了控制符、拉丁文,中、日、韩等绝大多数国际字符,但还不是所有,例如手机端常用的表情字符 emoji表情和一些特殊字符,这些需要四个字节才能编码出来的,就需要对utf8进行扩展,于是就有了utf8mb4。
MySQL想要插入 4 字节长度的 UTF-8 字符,就需要使用 utf8mb4 字符集(mb4就是most bytes 4的意思,专门用来兼容四字节的unicode),但只有 5.5.3 版本以后的才支持。
问题模拟
创建数据表
CREATE TABLE `user` (
`id` int NOT NULL AUTO_INCREMENT,
`name` varchar(50) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '用户名',
`password` varchar(50) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '密码',
`role` varchar(15) DEFAULT NULL COMMENT '角色',
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET = utf8;
执行SQL语句
INSERT INTO `user` (name, password, role)
VALUE ('????', 'mypassword', 'admin');
提示报错信息
INSERT INTO `user` (id, name, password, role) VALUE (NULL, '????', 'mypassword', 'admin')
> 1366 - Incorrect string value: '\xF0\x9F\x98\x81\xF0\x9F...' for column 'name' at row 1
> 时间: 0.001s
解决办法
确认版本
由于在问题原因里已经说了,只有5.5.3版本以后才支持,所以需要将Mysql升级到指定版本之后,查询mysql数据库版本的方式如下:
-- 执行sql查询当前数据库的版本
select version();
修改编码格式
数据库的字符集编码是有优先级的:
优先级顺序为:数据库字符集 < 表字符集 < 字段字符集,当字符集不一致时,以小范围的为准,即字段设置的字符集优先级最高!
--修改数据库字符集
ALTER DATABASE `数据库名` CHARACTER SET = utf8mb4;
--修改表字符集
ALTER TABLE `表名` convert to character set utf8mb4;
--修改字段字符集
ALTER TABLE `数据库名`.`表名` MODIFY COLUMN `字段名` VARCHAR(20) CHARACTER SET
utf8mb4 COLLATE utf8mb4_general_ci NULL COMMENT '字段名称注释';
再尝试执行那条插入语句就可以了。
问题总结
utf8mb4是utf8的超集,理论上原来使用utf8,然后将字符集修改为utf8mb4,也基本不会对已有的utf8编码数据的读取产生什么影响,不过为了utf8确实是更节省空间,我们一般情况下使用utf8也就够了,如果存在不确定输入内容是什么的时候,最好是使用 utf8mb4,利用增大空间的方式提升系统稳定性。
评论区