MySQL使用时,有一件很痛苦的事情确定是结果乱码。将编码格式都设置为UTF8能够解决这个问题,咱们今天来讲下为何要这么设置,以及怎么设置。html
在编程语言中,咱们为了防止中文乱码,会使用unicode
对中文字符作处理,而为了下降网络带宽和节省存储空间,咱们使用UTF8进行编码。对这二者有什么不一样不够了解的同窗,能够参考Unicode字符集和UTF8编码编码的前世此生这篇文章。mysql
一样在MySQL中,咱们也会有这样的处理,咱们能够查看当前数据库设置的编码方式(字符集):sql
mysql> show variables like '%char%'; +--------------------------+----------------------------------+ | Variable_name | Value | +--------------------------+----------------------------------+ | character_set_client | latin1 | | character_set_connection | latin1 | | character_set_database | latin1 | | character_set_filesystem | binary | | character_set_results | latin1 | | character_set_server | latin1 | | character_set_system | utf8 | | character_sets_dir | /usr/local/mysql/share/charsets/ | +--------------------------+----------------------------------+ 8 rows in set (0.00 sec)
表中就是当前设置的字符集,先看不用关注的几个值:数据库
character_set_filesystem | binary:
文件系统上的存储格式,默认为binary
(二进制)character_set_system | utf8:
系统的存储格式,默认为utf8
character_sets_dir | /usr/local/mysql/share/charsets/:
可使用的字符集的文件路径剩下的几个就是平常影响读写乱码的参数了:- character_set_client:
客户端请求数据的字符集- character_set_connection:
从客户端接收到数据,而后传输的字符集- character_set_database:
默认数据库的字符集;若是没有默认数据库,使用character_set_server
字段- character_set_results:
结果集的字符集- character_set_server:
数据库服务器的默认字符集编程
字符集的转换流程分为3
步:segmentfault
character_set_client
字符集MySQL
实例收到客户端发送的数据后,将其转换为character_set_connection
字符集进行内部操做时,将数据字符集转换为内部操做字符集:服务器
character set
设定值default character set
设定值default character set
设定值character_set_server
设定值character_set_results
说字符序以前,咱们须要了解一点基础知识:网络
(Character)
是指人类语言中最小的表义符号。例如’A’、’B’
等;(Encoding)
。例如,咱们给字符’A’
赋予数值0
,给字符’B’
赋予数值1
,则0
就是字符’A’
的编码;(Character Set)
。例如,给定字符列表为{‘A’,’B’}
时,{‘A’=>0, ‘B’=>1}
就是一个字符集;(Collation)
是指在同一字符集内字符之间的比较规则;(Default Collation)
;MySQL
中的字符序名称听从命名惯例:以字符序对应的字符集名称开头;以_ci
(表示大小写不敏感,case insensitive
)、_cs
(表示大小写敏感,case sensitive
)或_bin
(表示按编码值比较,binary
)结尾。例如:在字符序“utf8_general_ci”
下,字符“a”
和“A”
是等价的;所以字符序不一样于字符集,用于数据库字段的相等或大小比较。咱们查看MySQL
实例设置的字符序:编程语言
mysql> show variables like 'collation%'; +----------------------+-------------------+ | Variable_name | Value | +----------------------+-------------------+ | collation_connection | latin1_swedish_ci | | collation_database | latin1_swedish_ci | | collation_server | latin1_swedish_ci | +----------------------+-------------------+ 3 rows in set (0.00 sec)
跟utf8对应的经常使用字符序是:utf8_unicode_ci/utf8_general_ci和utf8_bin
等,那么他们的区别是什么呢?测试
_bin
是用二进制存储并比较,区别大小写,存储二进制内容时使用utf8_general_ci
:校对速度快,但准确度稍差,使用中英文时使用utf8_unicode_ci
:准确度高,但校对速度稍慢,使用德法俄等外语时使用详细的区别能够参考 Mysql中的排序规则utf8_unicode_ci、utf8_general_ci的区别总结。
若是在MySQL
链接时,出现了乱码的问题,那么基本能够肯定是各个字符集/序设置不统一的缘由。MySQL
默认的latin1
格式不支持中文,因为咱们在中国,因此选择对中文和各语言支持都很是完善的utf8
格式。因此,咱们须要将须要关注的字符集和字符序都修改成utf8
格式。
你也能够选择utf8mb4
格式,这个格式支持保存emoji😈
表情。
咱们须要修改Mysql的配置文件,查看配置文件的位置有两种方式:
1. $ mysql --help | grep 'my.cnf' /etc/mysql/my.cnf /etc/my.cnf ~/.my.cnf 2. ps aux | grep mysql
在(1)
中,/etc/my.cnf, /etc/mysql/my.cnf, ~/.my.cnf
这些就是mysql默认会搜寻my.cnf的目录,优先级依次升高。能够在各个配置文件里都使用long_query_time
来测试一下。
而后,咱们修改或新增下面的配置项:
# 下面注释的几行能够不设置,但若是你的没有生效,也能够试试看 [mysqld] character_set_server=utf8 collation-server=utf8_general_ci skip-character-set-client-handshake #init_connect='SET NAMES utf8' #[client] #default-character-set=utf8
这三行配置就能够解决问题,最关键的是最后一行,参考mysql文档,使用该参数会忽略客户端传递的字符集信息,而直接使用服务端的设定;再加上咱们设定服务端的字符集和字符序均为utf8
,这样就保证了字符格式的统一,解决乱码的问题。
重启mysql
服务,若是提示找不到服务,请参考用service命令管理mysql启停:
$ service mysqld restart Shutting down MySQL.. [ OK ] Starting MySQL. [ OK ]
链接到mysql
,查看当前编码:
mysql> show variables like '%char%'; +--------------------------+----------------------------------+ | Variable_name | Value | +--------------------------+----------------------------------+ | character_set_client | utf8 | | character_set_connection | utf8 | | character_set_database | utf8 | | character_set_filesystem | binary | | character_set_results | utf8 | | character_set_server | utf8 | | character_set_system | utf8 | | character_sets_dir | /usr/local/mysql/share/charsets/ | +--------------------------+----------------------------------+ 8 rows in set (0.01 sec) mysql> show variables like 'collation%'; +----------------------+-----------------+ | Variable_name | Value | +----------------------+-----------------+ | collation_connection | utf8_general_ci | | collation_database | utf8_general_ci | | collation_server | utf8_general_ci | +----------------------+-----------------+ 3 rows in set (0.01 sec)
能够看到一切都符合预期,请求和存储的数据也再也不是乱码了。
unknown variable 'default-character-set=utf8'
参考官方文档,该参数自5.5.3
版本废弃,改成了character-set-server
,改成这个参数便可。
但这个是在[mysqld]
下的配置,在[client]
下的配置依然使用default-character-set
参数。