一、MySQL 与 set names 有关的三个变量:

1. character_set_client:只是用来(向MySQL服务器)说明客户端使用的sql语句采用的是什么编码,并不会进行转换。

2. character_set_connection:见MySQL文档。

3. character_set_result:见MySQL文档。

值得注意的是另外两个变量: 

character_set_server 与 character_set_database:他们是用来指示MySQL最终以什么样的编码把数据存到磁盘上,这时会做必要的变换(这一点从实践中得出,MySQL文档中未提到)。其他信息见MySQL文档。

 

二、character_set_client只起到标示的作用,而且标示得不一定对。那么我客户端的编码究竟是什么?

分三个情景:

1. 在终端中直接写上SQL语句,如 insert into tb_temp(null, "情景一");  这里语句的编码是由locale决定的,通过LANG设置。locale 决定了键盘的输入和终端的显示(这里的“显示”,因理解为终端的输出缓存里的字符的编码)(在某终端里设置,只对该终端有效)。比如,LANG=zh_CN.gbk,那么语句是gbk编码的;LANG=zh_CN.utf8,那么语句是utf8编码的。如果输入到终端的是乱码,那么是 locale的设置 和 终端上的用来解析输出缓存里的字符的编码不一致。

这里顺便提到VIM。有时在VIM中会遇到乱码的情况。encoding变量默认情况下与locale的设置相同。说明文档(:set encoding-names 查看)指出,如果这两者不一致,vim会帮我们转换。前提是你要装好libiconv。不然除了不会给你自动转换,而且一些字符集如gb2312它会提示没有。在VIM命令模式下,使用set fenc? 来查看当前文件的编码。用“set fenc=” 可将文件设置成另一种编码,这也需要libiconv的支持。

我的.vimrc文件内容如下: 

*****************************

  set nu

  set tabstop=4

  set encoding=utf8

  set fileencoding=utf8

  set fileencodings=utf8,chinese,Latin1

*********************************

若不设置fileencodings(工作原理见说明文档),vim中默认fileencodings=ucs-bom,utf-8,latin1。这样的情况下,你的gbk文件在vim是乱码的,因为被当成Latin1编码来显示。fileencoding是用来指定你创建一个文件时所用的编码。(显然,若不设置fileencoding,那么新建的文件会保存成encoding指定的格式)。fileencoding需要与fileencodings配合使用才行。

这样设置好后,便能在LANG=zh_CN.utf8的情况下,编辑gbk以及其他格式的文件。
 
2.在console里粘贴数据
这种情况下,粘贴进的数据是在终端解释数据所用的字符集里,跟locale无关。
 
3.使用脚本文件进行mysql的操作
比如 mysql > source /home/aa/test.sql
那么所执行的sql语句的编码与其所在的文件的编码一致。
 
 
三、实践指导意义:
1.
mysql数据库的my.cnf 增加如下设置:
[mysqld]
default-character-set = utf8  #以便能存储任何编码的数据
2.
保证程序进行数据库操作前都使用set name xx, 就不会出现乱码。 若进数据库发现有乱码,试着改character_set_result;