时间:2021-07-01 10:21:17 帮助过:8人阅读
MySQL的客户端可以分为两种:一种就是用C语言写的官方客户端――MySQL命令程序;一种就是平常程序员使用JDBC等connector API写成的客户端。这里只讨论第一种。
MySQL命令程序在Windows和Linux系统中关于字符编码处理的部分并不等效,下图是Windows系统的客户端字符编码转换逻辑:
其中的三个character变量存在于服务器上,而charset_info存在于客户端。
当客户端启动连接到服务器时,客户端将根据配置参数设置charset_info为指定编码,同时通知服务器让服务器把三个character变量设置为相同编码。
由于在Windows平台上MySQL程序在读取控制台时使用了Unicode Console Read API,所以程序从控制台获取的原始字符串实际上是UTF16编码,所以这里的“操作系统编码”并不是Windows通常的GBK,而应该看做UTF16。
下图是Linux系统中的MySQL客户端程序字符编码转换逻辑:
vcyoTXlTUUy/zbuntsuy6dGvzazSu7j2se21w7W9tcTItMrHwtLC66GjPGJyPgq/ydLU1eLR+cSjxOLJz8r2tcTH6b/2o7o8YnI+CrS0vajSu7j2se2jrMbk1tDWu7D8uqzSu7j2R0JL19a3+7Su19a2zrrNVVRGONfWt/u0rtfWts6ho0xpbnV41tDG9LavTXlTUUzBrL3Ttb3K/b7dv+K3/s7xxvejrL2rt/7O8cb3tcTI/bj2Y2hhcmFjdGVyseTBv7TTxKzIz7XEVVRGONDeuMTOqkdCS6Gjz/LK/b7dv+Ky5cjr1tDOxMr9vt2jrMGivLRzZWxlY3SjrL3hufvO3tLss6OjujwvcD4KPHA+PGltZyBzcmM9"http://www.bitsCN.com/uploadfile/Collfiles/20140714/2014071409163740.png" alt="/">
但是使用Windows的MySQL客户端查询时,结果却是乱码:
结合前面的数据传输流程,就能知道问题出在什么地方:
客户端从终端读取了一行utf8编码(Linux默认)的命令文本,忽略charset_info变量,直接把文本发送给服务器;服务器因为事先的命令charset gbk把三个character变量都设置为了GBK,所以服务器认为收到的文本是GBK编码;接下来服务器会不经过任何转码将文本字符串直接存入数据表中,因为数据表第一个字段也是GBK。到这里为止,数据表中存了一个UTF8字符串,而服务器却当它是GBK,在同一个Linux客户端查询时:如果Windows客户端也想看到正确的结果,那就要故意错误地配置:
执行命令charset utf8,这会将charset_info和三个服务器character都设置为UTF8;执行命令set names gbk,这只会将三个服务器character设置为GBK;现在select,结果看上去不再乱码了。