Mysql数据库中文乱码问题之解决方法

时间:2022-06-29 00:28:27

这是一个在工作中遇到的真实案例,经过几天的摸索终于将问题解决了,现用文字记录下来,方便遇到类似问题的朋友参考。


在进入正题前,先介绍一下这个案例背景。

前段时间由于工作原因,需要将mysql数据库迁移到一台新服务器上,新机器操作系统用的是Windows Server 2008 R2,mysql的版本是5.5.28。直接使用了Navicat的备份功能将数据库备份,然后恢复到新的服务器上,将应用程序连接到新服务器上的数据库。测试后一切操作正常,数据提交后亦可以正确保存(包括中文)。

我们单位内部有一个接口程序,需要将mysql数据库中数据同步到mssql数据库中,然后再将mssql数据库有更新的数据回写到mysql数据库中。问题就在这时候出现了,从mssql中读取的中文写到mysql中全部变成了问号(?),只有数字和字母是保持不变!!


发现问题第一思路就是去改写这个负责数据同步的接口程序,因为这支程序是用Delphi写的,Delphi一向对双字节字符串支持不是很好,可是经过跟踪调试,发现读和写的中文数据都是正确的,只是在Navicat中显示的是问号。

于是又回头检查PHP连接mysql这段程序,发现没有明确指定字符集,而是使用mysql数据库默认的,细细想想在创建数据库的时候是指定使用utf8编码的呀!!于是试着在程序中显示的修改数据库字符集,set names utf8, 执行这句后,又一个有意思的情况出现了,就是被回写到mysql数据库中的中文(原先显示的是问号的)现在可以正确显示了,而原来可以正确显示的中文却变成了乱码(注意,这里的乱码不是问号,是真正的完全无法读懂的乱码了)。


停止对程序的debug,让自己静下来,捋捋思路。这时候我觉得问题应该出在mysql数据库这端,不是程序代码上的问题,因为这个问题是在数据库迁移到新服务器之后没多久才呈现出来。

连上mysql服务器,使用命令show variables like 'chara%';  果然发现了问题,character-set-server 是latin1, character-set-connection、character-set-client和character-set-results都是utf8。原来是server和client使用的编码方式不一致才导致出这样问题,那么问题来了,如何对数据库中的数据进行转码操作呢?操作如下:


1.先使用mysqldump命令将数据导出,记得要指定编码方式,否则导出来,中文也会是乱码。

mysqldump -uroot -p --default-character-set=latin1 DATABASENAME > FILENAME

2.使用文本编辑器打开刚刚导出的文件,将其中所有latin1替换为utf8,排序规则使用utf8-general-ci

3.最重要的一点,在保存文件时,一定要将编码方式改为utf8。

4.使用mysql命令将数据导入到新建的数据库中。

mysql -uroot -p DATABASENAME < FILENAME


到此问题解决。


但又发现一个问题,新创建的数据库在Navicat中,所有的中文均显示为问题(?)。这又是闹哪样呀!!!在navicat中使用show variables like 'chara%';查看一下,character-set-client还是latin1,这个和我们在mysql中的设置不一致,这个问题的解决方法是在连接上点右键,选择“连接属性”,在高级页面中,选择“使用mysql字符集”即可。