MySql字符集修改

问题分析

  1. 普通的字符串或者表情都是占位3个字节,所以utf8足够用了,但是移动端的表情符号占位是4个字节,普通的utf8就不够用了,为了应对无线互联网的机遇和挑战、避免 emoji 表情符号带来的问题、涉及无线相关的 MySQL 数据库建议都提前采用 utf8mb4 字符集,这必须要作为移动互联网行业的一个技术选型的要点
  2. Mysql 版本的限制,Mysql 5.5.3之前的版本,支持的utf8为3字节的,Mysql 5.5.3之后的版本支持utf8mb4

解决方案

首先我们看下哪些地方可能需要我们修改编码:

  1. 库(database)的编码
  2. 表(table)的编码
  3. 字段(column)的编码
  4. 程序中,数据库的连接url
  5. mysql的配置文件my.conf中

我们可以先查询下当前数据库的编码信息:

SHOW VARIABLES LIKE 'character_set_%'
Variable_nameValue
character_set_clientutf8
character_set_connectionutf8
character_set_databaseutf8
character_set_filesystembinary
character_set_resultsutf8
character_set_serverutf8
character_set_systemutf8
character_sets_dir/opt/install/mysql/share/charsets/

我们将库的编码修改

datebase charset=utf8mb4 
datebase collation=utf8mb4_unicode_ci

将表的编码修改

character set=utf8mb4
collation=utf8mb4_unicode_ci

将需要支持emoji表情字段的编码修改

Charset=utf8mb4
Collation=utf8mb4_unicode_ci

修改mysql的配置文件my.conf

[client]
# 客户端来源数据的默认字符集
default-character-set = utf8mb4

[mysql]
# 数据库默认字符集
default-character-set = utf8mb4

[mysqld]
# 服务端默认字符集
character-set-server=utf8mb4
# 连接层默认字符集
collation-server=utf8mb4_unicode_ci

修改完毕后,记得重新启动mysql服务

/etc/init.d/mysql restart

修改后,刷新连接后查看相关变量:

Variable_nameValue
character_set_clientutf8mb4
character_set_connectionutf8mb4
character_set_databaseutf8mb4
character_set_filesystembinary
character_set_resultsutf8mb4
character_set_serverutf8mb4
character_set_systemutf8
character_sets_dir/opt/install/mysql/share/charsets/

实测:修改项目中的连接数据库的url,将characterEncoding=utf-8去掉,实测此步骤可以不用改变。

字符集知识扩展

  1. 字符集、连接字符集、排序字符集

utf8mb4对应的排序字符集有utf8mb4_unicode_ci、utf8mb4_general_ci.

  • utf8mb4_unicode_ci和utf8mb4_general_ci的对比:
  • 准确性:

    • utf8mb4_unicode_ci是基于标准的Unicode来排序和比较,能够在各种语言之间精确排序
    • utf8mb4_general_ci没有实现Unicode排序规则,在遇到某些特殊语言或者字符集,排序结果可能不一致。
    • 但是,在绝大多数情况下,这些特殊字符的顺序并不需要那么精确。
  • 性能

    • utf8mb4_general_ci在比较和排序的时候更快
    • utf8mb4_unicode_ci在特殊情况下,Unicode排序规则为了能够处理特殊字符的情况,实现了略微复杂的排序算法。
    • 但是在绝大多数情况下发,不会发生此类复杂比较。相比选择哪一种collation,使用者更应该关心字符集与排序规则在db里需要统一。

至于排序规则(collation) 选择默认的 utf8mb4_general_ci,还是 utf8mb4_unicode_ci。 请参考stack overflow的这篇帖子。 讨论结果从排序的准确性,以及性能方面,告诉我们应该选用 utf8mb4_unicode_ci

相关推荐