24小时热门版块排行榜    

查看: 291  |  回复: 8
当前主题已经存档。

德娴

金虫 (小有名气)

[交流] MYSQL数据库字符集问题,出现乱码了

justdoit!
已阅   回复此楼   关注TA 给TA发消息 送TA红花 TA的回帖

mayong11

铁杆木虫 (职业作家)

不知道,帮你顶一下
学海无涯,重在交流
2楼2009-04-14 15:32:06
已阅   回复此楼   关注TA 给TA发消息 送TA红花 TA的回帖

entomology557

铁杆木虫 (知名作家)


德娴(金币+1,VIP+0): 4-15 10:04
这个。。。。先用前端的数据库查看器看一下现在用的是什么字符集,一般用utf8应该不会有中文乱码的问题,另外就是你程序读数据库的时候,需要注意一下字符的对应关系,不对应需要用程序转换一下。
生物进化基本常识:一定范围内,选择压力越大,要么进化的越快来适应这种压力,或者直接被淘汰。
3楼2009-04-14 15:34:05
已阅   回复此楼   关注TA 给TA发消息 送TA红花 TA的回帖

lukq2041

木虫 (著名写手)

友情支持
4楼2009-04-14 16:06:39
已阅   回复此楼   关注TA 给TA发消息 送TA红花 TA的回帖

myplum

木虫 (小有名气)

也不清楚,帮忙顶一下了嘿嘿嘿
5楼2009-04-14 19:04:28
已阅   回复此楼   关注TA 给TA发消息 送TA红花 TA的回帖

德娴

金虫 (小有名气)

谢谢支持,三楼说的试过了,不行.
justdoit!
6楼2009-04-15 10:04:21
已阅   回复此楼   关注TA 给TA发消息 送TA红花 TA的回帖

entomology557

铁杆木虫 (知名作家)

★ ★ ★ ★ ★ ★
德娴(金币+6,VIP+0):谢谢你,我的问题解决了,由于具体情况不同,虽然不是你文中所提到的方法,但仍有参考价值. 4-17 13:35
看了以下乱码的原因及解决方案,应该就知道怎么弄了。

MySQL乱码问题深层分析

一、概述
公司新购了一批PC,准备把几个性能较优的PC升级为数据库服务器,替换老旧的机器。公司有套POS终端软件,后台数据存储是MySQL3.23版。我准备硬件升级的同时升级数据库软件。但是升级过程中遇到闻名的MySQL的乱码问题。经过查找资料,加上自己的摸索和经验,终于完美地解决这个问题。
MySQL的乱码问题(不仅仅包括中文乱码,也包括其它语言的乱码,以下称之为乱码问题)只存在于4.1及其以上版本。4.1之前的MySQL不支持多语言,所以它会将你给它的数据“原封不动”地保存,再“原封不动”地读出来。从字节的角度来看,数据在这一过程中不会产生任何变化,因此不会有乱码。
4.1及以后的版本开始支持多语言,这个所谓的多语言,就是在输入输出时MySQL会替你做编码转换。而这个转换规则就是由客户端编码和服务器端编码来决定的。
编码转换的规则就是,在输入数据时将编码由“客户端编码”转换为“服务器端编码”,输出时将数据由“服务器端编码”转换为“客户端编码”。
二、乱码产生原因
MySQL字符编码是版本4.1引入的,支持多国语言,而且一些特性已经超过了其它大多数数据库管理系统。正因为这一特性才导致MySQL的乱码问题。
字符集是一套符号和编码。校对规则是在字符集内用于比较字符的一套规则。让我们使用一个假想字符集的例子来区别清楚。
假设我们有一个字母表使用了四个字母:‘A’、‘B’、‘a’、‘b’。我们为每个字母赋予一个数值:‘A’=0,‘B’=1,‘a’=2,‘b’=3。字母‘A’是一个符号,数字0是‘A’的编码,这四个字母和它们的编码组合在一起是一个字符集。
假设我们希望比较两个字符串的值(在if……else语句中我们经常做值的比较):‘A’和‘B’。比较的最简单的方法是查找编码:‘A’为0,‘B’为1。因为0小于1,我们可以说‘A’小于‘B’。我们做的仅仅是在我们的字符集上应用了一个校对规则。校对规则是一套规则(在这种情况下仅仅是一套规则):“对编码进行比较。”我们称这种全部可能的规则中的最简单的校对规则为一个binary(二元)校对规则。
但是,如果我们希望小写字母和大写字母是等价的,应该怎样?那么,我们将至少有两个规则:(1)把小写字母‘a’和‘b’视为与‘A’和‘B’等价;(2)然后比较编码。我们称这是一个大小写不敏感的校对规则。比二元校对规则复杂一些。
在实际生活中,大多数字符集有许多字符:不仅仅是‘A’和‘B’,而是整个字母表,有时候有许多种字母表,或者一个东方的(比如中文、日文、韩文、藏文、泰文等等)使用上千个字符的书写系统,还有许多特殊符号和标点符号。并且在实际生活中,大多数校对规则有许多个规则:不仅仅是大小写不敏感,还包括重音符不敏感(“重音符”是附属于一个字母的符号,象德语的‘?’符号)和多字节映射(例如,作为规则‘?’=‘OE’就是两个德语校对规则的一种)。
(以上摘自MySQL5.1手册。更多内容可参见:http://dev.mysql.com/doc/refman/5.1/zh/charset.html)
MySQL4.1.x开始支持以下这些事情
l使用多种字符集(CharacterSet)来存储字符
l使用多种校对规则(Collation)来比较字符串
l在同一台服务器、同一个数据库或甚至在同一个表中使用不同字符集或校对规则来混合字符串
l允许定义任何级别的字符集和校对规则
MySQL4.1及以上版本的字符集支持(CharacterSetSupport)有两个方面:字符集(CharacterSet)和校对规则(Collation)。字符集和校对规则有4个级别的默认设置:服务器(server),数据库(database),数据表(table)和连接(connection)。
MySQL中是根据下面几个变量确定服务器端和客户端用的什么字符集:
character_set_client    客户端字符集
character_set_connection  客户端与服务器端连接采用的字符集
character_set_results     SELECT查询返回数据的字符集
character_set_database    数据库采用的字符集
MySQL的字符集处理是这样的:
1、发送请求。
1)客户端发送请求到服务器端。
2)服务器端会把请求的数据从客户端字符集(character_set_client)转成服务器连接字符集(character_set_connection)。
3)然後服务器会检测存储区域(table,column)的字符集,然后把数据从连接字符集(character_set_connection)转为存储区域(table,column)的字符集,然後再存储或者查询。
2、返回请求。
1)服务器将存储区域(table,column)的字符集转换成服务器连接字符集(character_set_connection)。
2)将服务器连接字符集(character_set_connection)转换成结果字符集(character_set_results),再发送到客户端。
例如,我建立一个字符集为gbk的数据库(服务器端)。(MySQL4.1开始,在建立数据库时要指定它的字符集和校对规则,不指定就用默认的字符集和校对规则。)
连接数据库的程序(客户端)使用gb2312字符集(如windows命令行下使用MySQL,或者PHP连接MySQL),那么在执行insert命令时,insert的字符串将做一个gb2312到gbk的转换。而select时,数据库中保存的数据会先经过gbk到gb2312的转换之后再给你(结果集)。
好,那么为什么升级3.23(或4.0)到4.1时会乱码?举个例子说明。
例如3.23的数据库中保存的是gbk编码的数据。升级之前我将这些数据导出保存到文件里,这个文件的编码当然也是gbk的(因为3.23不支持多语言,不会对数据进行转换,也就是前面说的“原封不动地保存,原封不动地读出”)。
然后我在4.1中建立一个数据库,字符集为A;客户端字符集为B。将刚才的gbk数据导入。
1)A=gbk,B=gbk
导入数据时数据不会被转换;读出时需要setnamesgbk(setname命令下面将讲解)。
2)A=latin1,B=gbk
导入数据会进行gbk->latin1的转换,可能会丢失数据,产生乱码。
3)A=gbk,B=latin1
导入数据会进行latin1->gbk转换,可能会产生乱码。
4)A=latin1,B=latin1
导入数据时不会进行转换;读出时不需要setnamesgbk。
大家可以看到,上面1)、4)才是正确的做法,即让A和B使用同样的字符集才不会乱码。
三、解决方案
了解了MySQL4.1.x以上版本字符集处理的过程,我们就知道了怎么从原理上解决这个问题。
思路:让服务器端和客户端的字符集保持一致。
服务器端的编码是由字符集(CharacterSet)和校对规则(Collation)决定的。
上面提到,MySQL中是根据下面几个变量确定服务器端和客户端用的什么字符集:
character_set_client    客户端字符集
character_set_connection  客户端与服务器端连接采用的字符集
character_set_results     SELECT查询返回数据的字符集
character_set_database    数据库采用的字符集
也就是说,只要保证这几个变量采用一致的字符集,就不会出现乱码问题了。
生物进化基本常识:一定范围内,选择压力越大,要么进化的越快来适应这种压力,或者直接被淘汰。
7楼2009-04-15 12:29:15
已阅   回复此楼   关注TA 给TA发消息 送TA红花 TA的回帖

德娴

金虫 (小有名气)

entomology557 先试试看
justdoit!
8楼2009-04-15 17:41:11
已阅   回复此楼   关注TA 给TA发消息 送TA红花 TA的回帖

entomology557

铁杆木虫 (知名作家)

引用回帖:
Originally posted by 德娴 at 2009-4-15 17:41:
entomology557 先试试看

哈哈,真康侃,谢谢
生物进化基本常识:一定范围内,选择压力越大,要么进化的越快来适应这种压力,或者直接被淘汰。
9楼2009-04-17 13:39:18
已阅   回复此楼   关注TA 给TA发消息 送TA红花 TA的回帖
相关版块跳转 我要订阅楼主 德娴 的主题更新
普通表情 高级回复 (可上传附件)
信息提示
请填处理意见