discuz mysql 数据库编码转换latin1->utf8[ZT]

帮朋友的论坛做了一次编码转换的工作。系统是windows 2003,mysql4.1 discuz 5
本来以为很简单,dump数据

1
2
mysqldump -u root -p –opt –default-character-set=latin1 \
–skip-set-charset olddb cdb_members > d:\bak\cdb_members.sql

出来,用工具转一下编码,然后再导入

1
mysql -u root -p –default-character-set=utf8 newdb < d:\bak\cdb_members.sql

实际操作并没有想象的那么简单,最后解决的方案,也不是那么复杂。

先说一下教训,建立数据库的时候,同一个应用,所有的编码一定要一致, 不然就是自寻烦恼,现在跟你说,你肯定说不好,但是有时候就是不注意。要迁移的这个论坛就有两种编码gbk和latin1,目标是迁移到utf8,里面 gbk的双字节数据全部是乱码,尝试改编码也读不出数据了,由于不是重要数据,后来就放弃转码了,据说原来就有乱码的问题。

里面还遇到一个问题就是老的数据是更改过的,目标db是全新安装的,表结构不一致,好在新系统是老系统的子集,那么我就以老表为参照物,来改新db的表结构。

导出用了mysqldump,这里要提的是--default-character-set,后边要跟数据表的编码,不然导出的数据可能会乱码。

问题出在import,转编码后import,怎么也不成功,说什么mysql数据库gone away或者说duplicate,突然又一次成功,一看是因为建表语句的编码设置没有修改成utf8。

转编码用的ultraedit的转换功能,后来怀疑ultraedit的转换出错,网上找了一个win版本的iconv装上

1
iconv -f ISO-8859-1 -t UTF-8 original.txt> newfile.txt

问题依旧。其中有几个小表,直接用导出的sql粘贴到phpmyadmin里运行就可以了,但是会员和帖子表肯定不能用这个办法。

还试用了把latin1的表修改字符,然后试图用convert转码
update cdb_members set username=CONVERT(username USING utf8),也没成功。

后来当我一筹莫展准备缴械的时候,想起了另外两个功能 SELECT INTO OUTFILELOAD DATA INFILE 是另外一种导入导出的方法。

贴出使用的sql:

1
2
3
4
5
6
7
8
9
10
11
12
SELECT
uid,nickname,site,alipay,
icq,qq,yahoo,msn,taobao,
location,customstatus,
medals,avatar,avatarwidth,
avatarheight,bio,signature,
sightml,ignorepm,groupterms,
authstr INTO OUTFILE 'd:/cdb_memberfields.txt'
FIELDS TERMINATED BY ","
OPTIONALLY ENCLOSED BY """"
LINES TERMINATED BY "\r\n"
FROM gench2.cdb_memberfields;

然后转换d:/cdb_memberfields.txt 的编码为utf8,可以用ultraedit或者iconv,然后load到新数据库的表

1
2
3
4
LOAD DATA INFILE 'd:/cdb_memberfields.txt' INTO TABLE cdb_memberfields
FIELDS TERMINATED BY ","
OPTIONALLY ENCLOSED BY """"
LINES TERMINATED BY "\r\n";

上面还有一个问题是TERMINATED,ENCLOSED的选取,如果选的不对,会load失败。

附1:共迁移了如下表
cdb_attachments
cdb_forums
cdb_memberfields
cdb_members
cdb_onlinetime
cdb_posts
cdb_threads

附2:google到的链接
http://gentoo-wiki.com/TIP_Convert_latin1_to_UTF-8_in_MySQL