MySQL乱码问题终极指南


当前第2页 返回上一页

测试语句是插入一个中文字符“你”,其utf8编码为"0xE4 0xBD 0xA0",

1. latin1发送包 


思考一下1:为什么客户端和连接都设置了latin1,但最终发送的是正确的utf8编码呢?

2. latin1接收包 


思考一下2:为什么接收到的还是正确的utf8编码?

3. latin1不显示乱码 


思考一下3:为什么latin1显示了正确的utf8字符?

4. utf8接收包 


思考一下4:为什么连接的字符集和数据库的字符集设置成一样了,接收的数据反而不是utf8了?(请与latin1接收数据包对比)

5. utf8显示包


思考一下5:为什么连接的字符集和数据库的字符集设置成一样了,显示反而乱码了? 

怎么样,上面的思考题是否都有答案了,如果没有,相信下面这幅图能够帮助你:

这个抓包案例的字符变化图解:


附:mysql字符编码操作技巧
【查看字符集设置】

mysql> show variables like '%char%';
+--------------------------+-----------------------------------------------------+
| Variable_name      | 说明                        |
+--------------------------+-----------------------------------------------------+
| character_set_client   | 客户端字符集                    |
| character_set_connection | 当前连接字符集                   |
| character_set_database  | 数据库字符集                    |
| character_set_filesystem | 文件系统字符集,不要修改,使用binary即可      |
| character_set_results  | 返回结果集字符集                  |
| character_set_server   | 服务器默认字符集,当数据库、表、列没有设置时,   |
|             |   默认使用此字符集                |
| character_set_system   | 固定为utf8                     |
+--------------------------+-----------------------------------------------------+ 

【修改字符集设置】
服务器的配置在服务器建立的时候就由DBA设置好了,不推荐后续再改
通过SET NAMES utf8命令同时设置character_set_client/character_set_connection/character_set_results的字符集
建议所有配置都设置成utf8

【问题答案】

思考一下1:为什么客户端和连接都设置了latin1,但最终发送的是正确的utf8编码呢?
客户端设置了latin1,而我的语句是从notepad++中写好的,是utf8格式的;
中文utf8是3个字节,而latin1是按照单个字节解析的,虽然进行了转换,但不会导致二进制内容的变化,但实际上mysql客户端认为我输入了3个latin1字符;
如果客户端设置的编码是2个字节的gbk,这时转换就会发生乱码,utf8的3个字节会被转换为1个gbk字符(可能是乱码,也可能不是乱码)加上一个西欧字符(小于128就是英文,大于128就是其它西欧文)

思考一下2:为什么接收到的还是正确的utf8编码?
这是因为mysql服务器从将数据从“列”的编码(utf8)转换为latin1了,而列存储的数据并不是真正的utf8的中文“你”对应的"0xe4 0xbd 0xa0",
而是后面抓包看到的“c3a4 c2bd c2a0”(6个字节),mysql服务器将utf8的c3a4转换为latin1的0xe4,c2bd转换为0xbd, c2a0转换为0xa0

思考一下3:为什么latin1显示了正确的utf8字符?
因为mysql客户端收到了mysql服务器转换后的"0xe4 0xbd 0xa0",并把这个数据当做latin1的3个字符处理,然后抛给终端(我的是SecureCRT),
SecureCRT又把这三个latin1当做uft8处理,结果中文的“你”就显示出来了。

思考一下4:为什么连接的字符集和数据库的字符集设置成一样了,接收的数据反而不是utf8了?(请与latin1接收数据包对比)
字符集都一样的情况下,整个流程中不需要进行编码转换,直接将存储的“c3a4 c2bd c2a0”返回给客户端

思考一下5:为什么连接的字符集和数据库的字符集设置成一样了,显示反而乱码了?
参考思考4,客户端收到数据后也直接抛给终端显示,终端认为是两个utf8字符,并且找到了对应字符并显示,但我们看不懂,所以知道是乱码了,但这两个字符显示并没有错,如果真正找不到字符,可能会显示问号或者字符集规定的缺省符号。

以上就是关于MySQL乱码问题大集合,希望能够帮助大家解决MySQL乱码问题,谢谢大家的阅读。

更多相关Mysql内容来自木庄网络博客


标签:Mysql

返回前面的内容

相关阅读 >>

怎样远程访问mysql数据库?

怎么看mysql安装在哪?

解决死锁的4种基本方法

mysql主键id的生成方式(自增、唯一不规则)

mysql中关于删除语句大全总结(上)

mysql中数据库覆盖导入的几种方式总结

mysql数据归档小工具mysql_archiver详解

mysql数据库索引操作总结

mysql怎么创建存储函数

关于生产库中遇到mysql的子查询示例详解

更多相关阅读请进入《mysql》频道 >>


数据库系统概念 第6版
书籍

数据库系统概念 第6版

机械工业出版社

本书主要讲述了数据模型、基于对象的数据库和XML、数据存储和查询、事务管理、体系结构等方面的内容。



打赏

取消

感谢您的支持,我会继续努力的!

扫码支持
扫码打赏,您说多少就多少

打开支付宝扫一扫,即可进行扫码打赏哦

分享从这里开始,精彩与您同在

评论

管理员已关闭评论功能...