通常状况下,咱们会设置MySQL默认的字符编码为utf8,可是近些年来,emoji表情的火爆使用,给数据库带来了意外的错误,就是emoji的字符集已经超出了utf8的编码范畴😄mysql
谈到字符编码问题,会让不少人感到头疼,这里不在深究各个字符编码的特色和理论,这里只说下Unicode和utf8字符编码的关系sql
1 |
Unicode是编码字符集,而UTF-8就是字符编码,即Unicode规则字库的一种实现形式。 |
简单的说在计算机内存中,统一使用Unicode编码,当须要保存到硬盘或者须要传输的时候,就转换为UTF-8编码数据库
用记事本编辑的时候,从文件读取的UTF-8字符被转换为Unicode字符到内存里,编辑完成后,保存的时候再把Unicode转换为UTF-8保存到文件vim
emoji是Unicode编码,在MySQL中使用utf8编码没法正常显示emoji的表情,为了解决这个问题,MySQL在5.5.3版本以后,引进了新的字符编码utf8mb4
,本篇文章主要介绍如何将已是utf8的database切换到utf8mb4字符编码安全
utf8mb4最明显的好处是解决了苹果挖的坑-推广了emoji表情。utf8mb4解决了MySQL数据库存储emoji表情的问题优化
utf8mb4是utf8的超集,理论上由utf8升级到utf8mb4字符编码没有任何兼容问题编码
安全第一,备份全部须要升级字符编码的数据库spa
utf8mb4是MySQL5.5.3版本以后支持的字符集,so,若是你须要使用这个字符集,前提条件是你的MySQL版本必须 >= 5.5.3rest
在MySQL中,能够为一个database设置字符编码,能够为一张表设置字符编码,甚至能够为某一个字段设置字符编码code
SHOW VARIABLES WHERE Variable_name LIKE 'character\_set\_%' OR Variable_name LIKE 'collation%';
show create database polarsnow;
show create table ps;
show full columns from ps;
ALTER DATABASE database_name CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci
虽然修改了database的字符集为utf8mb4,可是实际只是修改了database新建立的表,默认使用utf8mb4,原来已经存在的表,字符集并无跟着改变,须要手动为每张表设置字符集
ALTER TABLE table_name DEFAULT 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;
注:VARCHAR(191) 根据字段实例的类型填写
因为从utf8升级到了utf8mb4,一个字符所占用的空间也由3个字节增加到4个字节,可是咱们当初建立表时,设置的字段类型以及最大的长度没有改变。例如,你在utf8下设置某一字段的类型为TINYTEXT
, 这中字段类型最大能够容纳255字节,三个字节一个字符的状况下能够容纳85个字符,四个字节一个字符的状况下只能容纳63个字符,若是原表中的这个字段的值有一个或多个超过了63个字符,那么转换成utf8mb4字符编码时将转换失败,你必须先将TINYTEXT
更改成TEXT
等更高容量的类型以后才能继续转换字符编码
在InnoDB引擎中,最大的索引长度为767字节,三个字节一个字符的状况下,索引列的字符长度最大能够达到255,四个字节一个字符的状况下,索引的字符长度最大只能到191。若是你已经存在的表中的索引列的类型为VARCHAR(255)
那么转换utf8mb4时一样会转换失败。你须要先将VARCHAR(255)
更改成VARCHAR(191)
才能继续转换字符编码
SET NAMES utf8 COLLATE utf8_unicode_ci
becomes SET NAMES utf8mb4 COLLATE utf8mb4_unicode_ci
1 |
> vim /etc/my.cnf |
检查修改
1 |
mysql> SHOW VARIABLES WHERE Variable_name LIKE 'character\_set\_%' OR Variable_name LIKE 'collation%'; |
注:character_set_system 一直都会是 utf8,不能被更改
1 |
> mysqlcheck -u root -p --auto-repair --optimize --all-databases |
不要在MySQL上使用utf8字符编码,推荐使用utf8mb4
,至于为何,引用国外友人的一段话:
Never use utf8 in MySQL — always use utf8mb4 instead. Updating your databases and code might take some time, but it’s definitely worth the effort. Why would you arbitrarily limit the set of symbols that can be used in your database? Why would you lose data every time a user enters an astral symbol as part of a comment or message or whatever it is you store in your database? There’s no reason not to strive for full Unicode support everywhere. Do the right thing, and use utf8mb4. 🍻