MySQL存储数据乱码的问题解析

 更新时间:2015年05月07日 10:57:39   投稿:goldensun  
这篇文章主要介绍了MySQL存储数据乱码的问题解析,作者从实际使用中的多个方面定位其原因然后解决,需要的朋友可以参考下

mysql的字符集设置有多个层级,在mysql中存储中文,如果不能正确设置字符集,很容易出现数据乱码。今天就有一个用户反馈他数据库中的数据下午1点多开始出现了乱码。在这里,我分享下具体问题的排查过程,以及解决的办法。

(1)  排除客户端设置导致的显示乱码

如果用户设置的mysql character_set_client跟客户端显示的字符集不一致,很容易导致中文数据乱码。

设置session字符集为utf8:set names utf8,设置客户端显示字符集为utf8,然后从表中select出有乱码的数据。

201557105216605.jpg (821×583)

上面显示,在character_set_client跟客户端的字符集一致的情况下,还是出现了乱码,这个排除是用户显示字符集设置不对的可能。下面通过hex(item_title)列来查看这个列在底层的存储字符集是否正确。

201557105249811.jpg (811×149)

通过上面的查询,可以确认这个数据乱码不是显示问题,而是存储的数据内容本身就是错误的。

(2)  定位存储乱码原因

1>     用户确认这个记录插入时能够正常显示,但是后来update之后,数据就乱码了。根据这个信息到binlog中查找更改正确内容对应的update语句。

201557105315821.jpg (792×244)

201557105339521.jpg (737×771)

上面的binlog日志显示这个sql将原来数据库中正确的内容,更新成一堆乱码。所以导致数据库中的存储数据乱码。

从binlog日志可以看出在更新时,是用latin1的方式写入到数据库中。Update后面的set语句中item_title字段的内容是乱码的,所以确认是导入数据源本身内容有问题,从而导致更新后的数据乱码。跟用户确认这个update语句的更新内容,是先从库中load 出来,后拼接成的update sql,所以怀疑load出来的数据就已经是乱码了,然后直接用这个错误的数据更新原来正确的数据,导致所有的正确的数据乱码。所以,需要确认这个update导入的数据源是否正确,即load出来的数据是否是正确的。

2>     导入数据源确认

开启实例的全日志开关,然后比对日志,从上面update语句对应的连接运行的sql中查找数据导出语句,以及对应的字符集设置。

201557105423659.jpg (810×324)

从上面的日志内容可以看出,这个连接建立后没有进行任何字符集的设置,直接从数据库中将内容select出来。在mysql中,如果没有设置session级别的字符集,那么使用默认的配置,配置如下:

201557105448774.jpg (816×323)

即输出会按照latin1的格式显示。在默认字符集的配置下,手动运行SELECT `main_table`.* FROM `promo_item` AS `main_table` WHERE  promo_item_id ='500186324' 命令,可以发现,在character_set_results 设置为latin1的情况下,输出结果中的item_title确实为一堆问号。

201557105513089.jpg (794×572)

由于latin1不能正确表示中文字符,所以显示为一堆问号,用户直接将这个内容update 原来正确的内容,所以导致存储内容乱码。

(3)小结

在使用mysql存储中文字符时,需要注意以下几点:

1>     确认更新的数据源同mysql 的session级别的字符集保持一致,Session级别的字符集可以用set names charset_name来设置。

2>     如果要正确显示中文,需要将character_set_results设置为GBK或是utf8。同时,客户端的显示字符集需要跟character_set_results的配置一致。

相关文章

  • MySQL数据表合并去重的简单实现方法

    MySQL数据表合并去重的简单实现方法

    这篇文章主要给大家介绍了关于MySQL数据表合并去重的简单实现方法,文中通过示例代码介绍的非常详细,对大家学习或者使用MySQL具有一定的参考学习价值,需要的朋友们下面来一起学习学习吧
    2019-05-05
  • mysql 触发器实现两个表的数据同步

    mysql 触发器实现两个表的数据同步

    本文将介绍mysql 触发器实现两个表的数据同步,需要的朋友可以参考
    2012-11-11
  • MySQL中视图的使用及多表INNER JOIN的技巧分享

    MySQL中视图的使用及多表INNER JOIN的技巧分享

    做多表关联查询,如果表间关系非常清晰,结构简单,使用视图的方式比自己反复写复杂跨表SQL要容易的多
    2014-06-06
  • MySQL 数据库的监控方式小结

    MySQL 数据库的监控方式小结

    本文主要介绍了MySQL 数据库的监控方式小结,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2023-04-04
  • phpmyadmin 4+ 访问慢的解决方法

    phpmyadmin 4+ 访问慢的解决方法

    很多人用了phpmyadmin4以后的版本发现速度好像慢了很多,总结下,提供解决方法。
    2013-11-11
  • Mysql在线回收undo表空间实战记录

    Mysql在线回收undo表空间实战记录

    这篇文章主要给大家介绍了关于Mysql在线回收undo表空间的相关资料,文中通过示例代码介绍的非常详细,对大家学习或者使用Mysql具有一定的参考学习价值,需要的朋友们下面来一起学习学习吧
    2019-09-09
  • MySQL使用innobackupex备份连接服务器失败的解决方法

    MySQL使用innobackupex备份连接服务器失败的解决方法

    这篇文章主要为大家详细介绍了MySQL使用innobackupex备份连接服务器失败的解决方法,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2017-02-02
  • mysql5.6及以下版本如何查询数据库里的json

    mysql5.6及以下版本如何查询数据库里的json

    MySQL里面保存数据有时候会把一些杂乱且不常用的时候丢进一个json字段里面,那么如何查询数据库里的json呢以及mysql存储json注意那些格式呢?接下来通过本文给大家详细介绍,需要的朋友参考下
    2017-03-03
  • MySQL中or用法及mybatis or用法详解

    MySQL中or用法及mybatis or用法详解

    在SQL查询语句中,OR关键字用于连接两个或多个条件,表示满足其中一个条件即可,当使用OR时,如果第一个条件为真,则不会检查第二个条件;如果第一个条件为假,则会检查第二个条件,这篇文章主要介绍了MySQL中or用法及mybatis or用法总结,需要的朋友可以参考下
    2024-05-05
  • MySQL找出未提交事务信息的方法分享

    MySQL找出未提交事务信息的方法分享

    这篇文章主要给大家介绍了关于MySQL如何找出未提交事务信息的相关资料,文中通过示例代码介绍的非常详细,对大家学习或者使用MySQL具有一定的参考学习价值,需要的朋友们下面来一起学习学习吧
    2019-06-06

最新评论