解读
utf8是utf8mb4的子集,一般情况下,应该是可以直接修改表字符集的。
修改字符集的几种方法
方法一
- 修改表默认字符集
1 2 |
mysql> alter table j1 default character set utf8mb4; |
- 随后再修改所有字符型列的字符集
1 2 |
mysql> alter table j1 modify name varchar(20) character set utf8mb4 not null default ''; |
方法二
也是执行ALTER TABLE来修改,但有更简单的解法
1 2 |
mysql> alter table j1 convert to character set utf8mb4; |
备注
上面两种方法,其实是有区别的。
- 采用方法一,如果遇到某个列字符集转换完后字节数超限了,会提示错误。
-
而采用方法二,如果遇到某个列字符集转换完后字节数超限了,则会将这个列数据类型转换成可以容纳更大长度的类型,比如从 TEXT 转成 LONGTEXT 等。
方法三
如果不放心,可以用mysqldump逻辑备份方式,用utf8mb4字符集把数据备份出来,新建表,恢复回去,应该也可以的。
结论
想从小字节数(2字节/3字节)字符集(gb2312、utf8)转换到大字节数(4字节)字符集(utf8mb4),是可以直接转换的。
相反,想从大字节数字符集转成小的,则会有风险,例如字符串被截断等。
案例测试
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 |
yejr@imysql.com [test]>set names gb2312; yejr@imysql.com [test]>show create table t1; | t1 | CREATE TABLE `t1` ( `id` int(11) DEFAULT NULL, `name` char(2) NOT NULL DEFAULT '' ) ENGINE=InnoDB DEFAULT CHARSET=gb2312 yejr@imysql.com [test]>select * from t1; +------+--------+ | id | name | +------+--------+ | 232 | 你我 | | 47 | 你我 | | 3 | 你我 | | 5 | 你我 | | 8 | 你我 | | -1 | 你我 | +------+--------+ //直接修改字符集 yejr@imysql.com [test]>alter table t1 convert to character set utf8mb4; //把客户端工具的终端字符集从gb2312改成utf8 //同时修改mysql客户端字符集,重新读取数据 yejr@imysql.com [test]>set names utf8mb4; yejr@imysql.com [test]>select * from t1; +------+--------+ | id | name | +------+--------+ | 232 | 你我 | | 47 | 你我 | | 3 | 你我 | | 5 | 你我 | | 8 | 你我 | | -1 | 你我 | +------+--------+ |
可以看到,是可以直接转换的。
当然了,生产环境中,如果也想这么做,最好还是先在测试环境进行更严格的测试演练,确保无误后再实施。
参考
- https://dev.mysql.com/doc/refman/5.7/en/alter-table.html#alter-table-character-set
- https://dev.mysql.com/doc/refman/5.7/en/charset-unicode-conversion.html
- http://imysql.com/2013/11/19/problem-about-mysql-date-function-charset.shtml
- http://imysql.com/2013/10/29/misunderstand-about-charset-handshake.shtml
- http://imysql.com/charset_tips
- http://imysql.com/2007_12_16_mysql_faq_how_to_change_default_charset
- http://imysql.com/2007_12_23_mysql_faq_how_to_set_default_table_charset
- http://imysql.com/2007_12_25_mysql_faq_how_to_set_default_field_charset
- http://imysql.com/node/733