常见的导致mysql中文乱码问题
在mysql应用中导致mysql中文乱码的问题不意外就是编码问题了,但在编码问题上有服务器编码还是latin1或都数据库编码与程序页面编码未处理好,只要做到这两点mysql中文问题就可以解决了.
以前写过一篇有关如何处理mysql中文乱码的问题,结果发现还是有必要再写这一篇.
原因是很多时候,为了安全,不允许mysql管理工具连接线上的正式环境,这样的情况下,就不能依靠mysql管理工具来转换编码来解决中文乱码的问题.
这样的情况下只能通过putty或者secureCRT远程连接mysql server,然后通过mysql命令界面来对mysql数据库导出,再做其他的编码转换操作,我现在面临的环境就是这样.
现在,描述一下我的数据情况,我需要导出中文乱码的数据表account.user,代码如下:
- mysql>showcreatedatabaseaccount;
- +———-+——————————————————————————————+
- |Database|CreateDatabase|
- +———-+——————————————————————————————+
- |account|CREATEDATABASE`account`/*!40100DEFAULTCHARACTERSETutf8COLLATEutf8_unicode_ci*/|
- +———-+——————————————————————————————+
- 1rowinset(0.00sec)
- mysql>showcreatetableuser;
- +———————+———————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————–+
- |Table|CreateTable|
- +———————+———————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————–+
- |user_agreement_info|CREATETABLE`user`(
- `id`int(11)unsignedNOTNULLAUTO_INCREMENT,
- `uid`bigint(21)unsignedNOTNULL,
- `realname`char(32)NOTNULL,
- `id_type`smallint(11)unsignedNOTNULL,
- `id_num`char(32)DEFAULTNULL,
- `create_time`int(10)unsignedDEFAULTNULL,
- PRIMARYKEY(`id`),
- KEY`uid`(`uid`)
- )ENGINE=MyISAMAUTO_INCREMENT=129287DEFAULTCHARSET=utf8|
- +———————+———————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————–+
- 1rowinset(0.02sec)
- #查询数据乱码,看下面:
- mysql>select*fromuserlimit10;
- +—-+————+—————————+———+——————–+————-+
- |id|uid|realname|id_type|id_num|create_time|
- +—-+————+—————————+———+——————–+————-+
- |23|1000001229|�陈|1|410101234567891234|1272619237|
- |2|1000001207|�文鉴|1|320211198511261933|1272546559|
- |3|1000001208|蒋家锋|1|513023198808294915|1272547009|
- |4|1000001209|zhaojing|1|320822198704286120|1272550654|
- |5|1000001210|阮å°?æ¦|1|31020619840214283X|1272562857|
- |6|1000001211|黑夜精�|1|412723798204103835|1272588671|
- |7|1000001212|谢勇|1|330722198408168210|1272591799|
- |8|1000001213|邵�芳|3|0621316|1272592840|
- |9|1000001215|�维纪|1|330382198611030393|1272592959|
- |10|1000001216|谈�|1|430721198309272802|1272595142|
- +—-+————+—————————+———+——————–+————-+
- 10rowsinset(0.00sec)
- #数据库编码设置情况:phpfensi.com
- mysql>showvariableslike‘%char%’;
- +————————–+—————————————-+
- |Variable_name|Value|
- +————————–+—————————————-+
- |character_set_client|utf8|
- |character_set_connection|utf8|
- |character_set_database|utf8|
- |character_set_filesystem|binary|
- |character_set_results|utf8|
- |character_set_server|utf8|
- |character_set_system|utf8|
- |character_sets_dir|/usr/local/mysql/share/mysql/charsets/|
- +————————–+—————————————-+
- 8rowsinset(0.02sec)
这是什么问题呢?首先我们来看下数据是什么编码,代码如下:
- mysql>setnameslatin1;
- QueryOK,0rowsaffected(0.02sec)
- mysql>select*fromuser_agreement_infolimit10;
- +—-+————+————–+———+——————–+————-+
- |id|uid|realname|id_type|id_num|create_time|
- +—-+————+————–+———+——————–+————-+
- |23|1000001229|陈|1|410101234567891234|1272619237|
- |2|1000001207|王嘉文|1|320211198511261933|1272546559|
- |3|1000001208|网家锋|1|513023198808294915|1272547009|
- |4|1000001209|zaojing|1|320822198704286120|1272550654|
- |5|1000001210|小林|1|31020619840214283X|1272562857|
- |6|1000001211|黑夜精灵|1|412723798204103835|1272588671|
- |7|1000001212|凤舞|1|330722198408168210|1272591799|
- |8|1000001213|邵明芳|3|0621316|1272592840|
- |9|1000001215|王维纪|1|330382198611030393|1272592959|
- |10|1000001216|谈宏|1|430721198309272802|1272595142|
- +—-+————+————–+———+——————–+————-+
- 10rowsinset(0.01sec)
现在可以确定了,这个表里的数据时latin1编码的,我们知道如果要mysql中,中文正常显示,必须要保持编码一致,我们看到在数据库里执行set names latin1之后,中文就能正常显示,那么我们就按照这样的方式导出数据,代码如下:
[root@sh-db1 tmp]# /usr/local/mysql/bin/mysqldump -uroot –opt –default-character-set=latin1 -p654321 account user >/tmp/user.sql
注意这里的导出参数–default-character-set=latin1,也就是相当于我们在数据导出之前在数据库里执行set names latin1;
这样数据就以sql脚本的方式存在于server上,使用vim查看文件/tmp/user.sql时发现还是乱码,这是为什么呢?下面就是原因,代码如下:
- [root@sh-db1tmp]#locale
- LANG=en_US.UTF-8
- LC_CTYPE=”en_US.UTF-8″
- LC_NUMERIC=”en_US.UTF-8″
- LC_TIME=”en_US.UTF-8″
- LC_COLLATE=”en_US.UTF-8″
- LC_MONETARY=”en_US.UTF-8″
- LC_MESSAGES=”en_US.UTF-8″
- LC_PAPER=”en_US.UTF-8″
- LC_NAME=”en_US.UTF-8″
- LC_ADDRESS=”en_US.UTF-8″
- LC_TELEPHONE=”en_US.UTF-8″
- LC_MEASUREMENT=”en_US.UTF-8″
- LC_IDENTIFICATION=”en_US.UTF-8″
- LC_ALL=
还有跟你的连接工具的编码有关系,去查看一下你的putty或者secureCRT连接使用的是什么编码,这些不同的编码就是造成你使用vim查看中文显示乱码的原因.
没有关系,我们使用sz命令把/tmp/user.sql下载到本地,也就是你的windows主机上.
然后使用emedtor或者uedtor,notepad++,vim都可以,打开,发现中文已经可以正常显示,如果不正常显示,那就往前看看是不是哪里做错了,修改user.sql里面的内容,set names latin1;修改为set names utf8;然后另存为utf8的编码形式.
再使用rz上传到mysql server上,再次使用vim打开,发现中文正常显示,代码如下:
[root@sh-db1 tmp]# /usr/local/mysql/bin/mysql -uroot -S /tmp/mysql3306.sock -p654321 account < user.sql
登录mysql查看,中文显示正常.
最后总结了几点中文乱码问题:
1.server本身设定问题,例如还停留在latin1
2.table的语系设定问题(包含character与collation)
3.客户端程式(例如php)的连线语系设定问题
强烈建议使用utf8,utf8可以兼容世界上所有字符.
4.在网页代码中加上一个"set names utf8"或者"set names gbk"的指令,告诉MySQL连线内容都要使用 utf8或者gbk.
热门评论