大庆信息网 www.daqing123.com
 您现在的位置:大庆信息网 > 电脑网络 > 操作系统
Mysql 数据库字符集转换及版本升/降级教程
来源:转载  发布时间:2007-12-11 4:51:20

Mysql 数据库字符集转换及版本升级/降级的详细教程 0Q'<Db"!<  
=lwxqV\O=  
本文为穆亦风原创,原帖地址 http://club.muzone.cn/viewthread.php?tid=28605 ZT&:H =!  
转贴请注明出处,非常感谢! 0Gh%'HS)  
Cs["K9t.y  
最近discuz发布了新的版本,免费了,用的人更多了,以前使用其它论坛程序和discuz2.5/3.0的纷纷转换或升级到discuz4.0,可见discuz作为中国人开发的php论坛程序,确实是非常优秀的,在大家欣喜若狂的时候,也遇到了一些问题 '_>24UbR  
^tJ%C5|P  
看到不少用户反映转换完以后是乱码的情况,出现这种现象的主要原因是这类用户使用的都是mysql4.1以上的版本.下面作一个说明,希望出现这个问题的朋友都能耐心的把这个文档看完!!! 5SN Wg(5[  
6HDR/OH  
MySQL 4.1开始,对多语言的支持有了很大变化 (这导致了问题的出现)。尽管大部分的地方 (包括个人使用和主机提供商),MySQL 3、4.0 仍然占主导地位;但 MySQL 4.1 乃至5.0是 MySQL 官方推荐的数据库,已经有主机提供商开始提供并将会越来越多;因为 latin1 在许多地方 (下边会详细描述具体是哪些地方) 作为默认的字符集,成功的蒙蔽了许多 PHP 程序的开发者和用户,掩盖了在中文等语言环境下会出现的问题。 !9hpbb/  
| ZEZ@7LTj  
MySQL 4.1开始把多国语言字符集分的更加详细,所以导致数据库迁移,或则dz论坛升级到4.0后(dz4.0开始使用gbk或utf-8编码)出现乱码问题。 %nDDnxA_  
ch 7M1r  
MySQL 4.1的字符集支持(Character Set Support)有两个方面:字符集(Character set)和排序方式(Collation)。对于字符集的支持细化到四个层次: 服务器(server),数据库(database),数据表(table)和连接(connection)。 zd|a!jqVW  
V2e 9BktV  
查看系统的字符集和排序方式的设定可以通过下面的两条命令: #YAuO~d5  
,\( =B  
<(* hT8  
QUOTE: [WP Rt'1  
mysql> SHOW VARIABLES LIKE 'character_set_%'; Q/cr:yv  
+--------------------------+----------------------------+ rqW^\Sn  
| Variable_name | Value | , p5$+#r  
+--------------------------+----------------------------+ o5!,/95pQ  
| character_set_client | latin1 | \$L&` Qxk  
| character_set_connection | latin1 | 5:P)_-V  
| character_set_database | latin1 | C(0ANT  
| character_set_results | latin1 | 2Z+"DF  
| character_set_server | latin1 | GEIy]@D,6  
| character_set_system | utf8 | Re,Z3l2  
| character_sets_dir | /usr/share/mysql/charsets/ | nt-m#0U7  
+--------------------------+----------------------------+ )] WnrC  
7 rows in set (0.00 sec) >Y5 avD.  
XP ^$$Ed  
mysql> SHOW VARIABLES LIKE 'collation_%'; )2Tle#  
+----------------------+-------------------+ R188sOa_(  
| Variable_name | Value | c"fbMS  
+----------------------+-------------------+ ^ _&eac+c  
| collation_connection | latin1_swedish_ci | K)nt#wh /  
| collation_database | latin1_swedish_ci | SNzcO]Z  
| collation_server | latin1_swedish_ci | 6Uld"7&#N  
+----------------------+-------------------+ >?L"xAoon  
3 rows in set (0.00 sec) u8.|Rt09b  
n.x~:Tf:  
MySQL 4.1 对于字符集的指定可以细化到一台机器上安装的 MySQL,其中的一个数据库,其中的一张表,其中的一栏,应该用什么字符集。但是,传统的 Web 程序在创建数据库和数据表时并没有使用那么复杂的配置,它们用的是默认的配置,那么,默认的配置从何而来呢? k>,3wA  
l4T5{"3cm  
编译 MySQL 时,指定了一个默认的字符集,这个字符集是 latin1; 6c@(P' d  
安装 MySQL 时,可以在配置文件 (my.ini) 中指定一个默认的的字符集,如果没指定,这个值继承自编译时指定的; "%4aZb  
启动 mysqld 时,可以在命令行参数中指定一个默认的的字符集,如果没指定,这个值继承自配置文件中的; hRLl z99  
此时 character_set_server 被设定为这个默认的字符集; 13 J> ^!  
当创建一个新的数据库时,除非明确指定,这个数据库的字符集被缺省设定为 character_set_server; ,KmTRPrJ  
当选定了一个数据库时,character_set_database 被设定为这个数据库默认的字符集; V5qkyY-  
在这个数据库里创建一张表时,表默认的字符集被设定为 character_set_database,也就是这个数据库默认的字符集; 26%i>*07  
当在表内设置一栏时,除非明确指定,否则此栏缺省的字符集就是表默认的字符集; L68.&lv  
这个字符集就是数据库中实际存储数据采用的字符集,mysqldump 出来的内容就是这个字符集下的; @P [<9  
当我们按照原来的方式通过PHP存取MySQL数据库时,就算设置了表的默认字符集为utf8并且通过UTF-8编码发送查询,你会发现存入数据库的仍然是乱码。问题就出在这个connection连接层上。 HuBO`q{&Av  
想要进行“正确”的存储和得到“正确”的结果,最方便的是在所有query开始之前执行一下: gMZ|=' *  
Q@{?%Q!  
SET NAMES 'gbk'; u71 H&]QZ  
其中gbk是数据库字符集。 9|sujY_[  
:[Y[g*to-  
它相当于下面的三句指令: # 8 KjJ  
SET character_set_client = gbk; _s"v]hJP  
SET character_set_results = gbk; h"*CN5)f8  
SET character_set_connection = gbk; ,gk'?+d (i  
oJOU. =+H  
4.1和5.0默认使用的是latin1字符集(木头:妈的,老外真霸道,妄想让全世界都是使用瑞典字符集吗) tz+%I@q"Br  
如果我们只想使用gbk字符集存储和获取数据, m`]6FCku(  
我们在编译mysql 4.1和 5.0的时候,需要注意在my.ini或者my.cnf中添加两处参数 mv2B6Ob  
d30|C,Dp  
m$MaF2MM  
[Copy to clipboard] [ - ] -xuG jEj  
CODE: LD8Z_K  
[mysqld] 3Mn+ICr\*  
default-character-set=utf8 PUz "'(  
z) Z2  
m _%+b  
3{>;R@  
JpP1?]Nw>  
[Copy to clipboard] [ - ] rgrQ J #>  
CODE: )/RWCz ]  
#settings for clients (connection, results, clients) @L =M] .  
[mysql] :?nT4M|Y'-  
default-character-set=utf8 T$ 5k  
! ]p Y9z  
下面我们来说主题,如何转换数据库字符集 eX,{N  
两种方法, ;XDEd*b  
AWan-tHx  
 pAXK!L  
QUOTE: VqZoe6  
第一种----更改存储字符集 Diy_a   
主要的思想就是把数据库的字符集有latin1改为gbk,big5,或者utf8; 以下操作必须拥有主机权限。假设当前操作的数据库名为:database fLR$2h}0  
dAs7+?b  
导出 > tQv{/E.  
首先需要把数据导为mysql4.0的格式,具体的命令如下: K(` /8 ar  
mysqldump -uroot -p --default-character-set=latin1 --set-charset=gbk --skip-opt databse > d4.sql 1(D@p;/d  
u^ ,7U \)  
--default-characte-set 以前数据库的字符集,这个一般情况下都是latin1的, &]P4L  
--set-charset 导出的数据的字符集,这个可以设置为gbk,utf8,或者big5 t6N D%}Vp  
导入 G`sSkD$  
首先使用下面语句新建一个GBK字符集的数据库(test) "LT\gsL  
E'_UJ&  
CREATE DATABASE `d4` DEFAULT CHARACTER SET gbk COLLATE gbk_chinese_ci; 'S4 p*>y&  
然后把刚才导出的数据导入到当前的数据库中就ok了。 3U?R+ ltM  
Zheb8NU  
mysql -uroot -p --default-character-set=gbk -f d4<d4.sql x1<  
通过以上的导出和导入就把数据库的字符集改为正确的存储方式了。 !Nqpy(CB  
k?xR0~j  
其中d4为新建库的名称,d4.sql为导出文件的名字 f1so@ xv  
.:_]  
但是这种方法,发现数据库数据存储量无端变大30%,真是郁闷 'i ]H^91  
e]C4[-bR`  
Xl!`.k'  
cmGN5.^/  
o9)b*f[n  
QUOTE: 0Jg"z h\u  
另外一种其实原理相同,但是需要手动操作,一般用于第一种方法失败后的选择 }MM_zj_i  
不过这种方法如果数据库很大,估计很难做,因为光打开文件就能让你死机 H -R ;  
MHc9 Ip}P  
首先还是用phpmyadmin或者用mysql本身的dump导出 .sql文件 K>`&z~~;  
XE"= <2  
然后用UltraEdit打开你备份的所有xxxx.sql文件,查找 AnXGQ  
mD o'VM};  
$I.Sgi0  
[Copy to clipboard] [ - ] >G8Sbl|  
CODE: {Ot)8(  
DEFAULT CHARSET=latin1 6\<l\  
f#U]sS];  
latin1这里也许是别的,反正是你不想要的,要转成gbk或者big5的字符集 @ . sza  
把这个替换为“空” Cav 2v  
在查找 gYq7E q2  
x&:y\N   
)HoPz9V  
[Copy to clipboard] [ - ] ".A?h Dr(  
CODE: vay;g>?F  
CREATE TABLE cdb_sessions ( "{ \C_Wm  
sid char(6) character set latin1 collate latin1_bin NOT NULL default '', Br uG4ya  
ip1 tinyint(3) unsigned NOT NULL default '0', m23E o +  
ip2 tinyint(3) unsigned NOT NULL default '0', uMHmZ-  
ip3 tinyint(3) unsigned NOT NULL default '0', 2uzsTI?\~  
ip4 tinyint(3) unsigned NOT NULL default '0', i5~hD~~UP  
uid mediumint(8) unsigned NOT NULL default '0', fgg`lj  
username char(15) NOT NULL default '', Z7sOi+rO  
groupid smallint(6) unsigned NOT NULL default '0', DGLqSHz  
styleid smallint(6) unsigned NOT NULL default '0', < Z#zW@  
invisible tinyint(1) NOT NULL default '0', p #J .^dz  
`action` tinyint(1) unsigned NOT NULL default '0', .K5CDy  
lastactivity int(10) unsigned NOT NULL default '0', OjmLeF,&  
fid smallint(6) unsigned NOT NULL default '0', U:7:=K ~  
tid mediumint(8) unsigned NOT NULL default '0', \Rq3=(1  
nickname char(15) NOT NULL default '', -PYzW-|w  
UNIQUE KEY sid (sid) IC &_6v z  
) ENGINE=HEAP MAX_ROWS=1000; 8Osl\55v:  
w ~Jt2_ 4  
替换为 K}W%$!dI  
t,Fa;m/S  
q|V`4w  
[Copy to clipboard] [ - ] 1CTl  
CODE: YN@~~MP  
CREATE TABLE `cdb_sessions` ( + _FWL  
`sid` char(6) binary NOT NULL default '', q|Dz`Es  
`ip1` tinyint(3) unsigned NOT NULL default '0', PF iWp 2u  
`ip2` tinyint(3) unsigned NOT NULL default '0', 8c: ^_<-"  
`ip3` tinyint(3) unsigned NOT NULL default '0', 7!{@J4t  
`ip4` tinyint(3) unsigned NOT NULL default '0', +Js/EfrZ<  
`uid` mediumint(8) unsigned NOT NULL default '0', "7?u1 r  
`username` char(15) NOT NULL default '', 3[nCeGGjF  
`groupid` smallint(6) unsigned NOT NULL default '0', "r[,?ex?`  
`styleid` smallint(6) unsigned NOT NULL default '0', bW{7e'  
`invisible` tinyint(1) NOT NULL default '0', +F7& x!sl?  
`action` tinyint(1) unsigned NOT NULL default '0', O:41!S4^  
`lastactivity` int(10) unsigned NOT NULL default '0', <va^` %j  
`fid` smallint(6) unsigned NOT NULL default '0', pJ<KZ7F$  
`tid` mediumint(8) unsigned NOT NULL default '0', dH, 5wlr!  
`nickname` char(15) NOT NULL default '', g'ffmZ+A  
UNIQUE KEY `sid` (`sid`) wo7 sm  
) TYPE=HEAP MAX_ROWS=2000; N9*pr~RjD  
!@q^Xy^[?  
这一步更为简单的办法就是删除掉关于cdb_sessions表的这一段,将来全新装一个d4,将这个表导出 U!u#Q`e  
将其内容复制,粘贴到 sql文件的最后面 Tz6y'8~  
PX9Y,B3fs  
保存后,再把这个sql文件导入到你的库中 kD GCZis  
]@j~ <)B  
就OK了 gQ|0sA>)g  
5?n _or+'  
用这两种方法就可以很方便的把4.1和5.0的mysql数据库降级到4.0 G +*hVP  
简单的过程就是 wyB tNj%u  
A导出4.1/5.0的库 @ZK{x_  
B进行处理,转换成gbk字符集 .CRGP=8  
C彻底卸载4.1或者5.0 Ar/E-,dg2  
D安装4.0.26 9`B$ReK?d  
E然后导入处理完的库 M2 U 7  
!n]`Ss,G}  
降级的时候导出库可以用这个方法 I 4 lF>  
mysqldump -uroot -p --default-character-set=latin1 --set-charset=gbk --skip-opt databse --compatible=mysql40 > d4.sql :mbrSc:/  
这样导出的就是4.0的库勒 %67Ya'Vw  
UtY" xV  
至于mysql版本的升级, oBXsAy  
如果数据文件中有中文信息,那么将MySQL 4.0的数据文件,直接拷贝到MySQL 4.1中就是不可以的,即便在my.ini中设置了default-character-set为正确的字符集。虽然貌似没有问题,但MySQL 4.1的字符集有一处非常恼人的地方,以gbk为例,原本MySQL 4.0数据中varchar,char等长度都会变为原来的一半,这样存储中文容量不变,而英文的存储容量就少了一半。这是直接拷贝数据文件带来的最大问题。 d0NJEi  
'ut`vsn  
所以,升级的根本,如果想使用“正确”的字符集,还是先用mysqldump导出成文件,然后导入。

(编辑:daqing123) 进入论坛参与讨论 留言给网站
在线投稿】【打印】【关闭】【顶部

相关文章:

·利用实例讲解MySQL数据库做到查询最优化
·MySQL5.0 不能使用自动增加字段问题解决
·在MySQL数据库中如何修改密码及访问限制
·MySQL数据库中数据库移植中的乱码问题
·搞定MySQL数据库中文模糊检索问题
·MySQL常见错误提示及解决方法
·怎样在Mysql中直接储存图片
·带你轻松接触Oracle 9i的内存泄漏问题
·怎样修改MySQL数据库中一个用户的密码
·不能通过mysql.sock连接MySQL问题的方法
特别推荐



Copyright © 2003-2008 ™ daqing123.com.All Rights Reserved.
网站帮助中心 | 网站联系方式