场景说明:
1、现上几百台mysql数据库,字符编码latin1,现在需要做一个活动,将现上mysql数据库的一些活动数据同步到一台mysql汇总数据库(latin1),然后再将数据同步oracle中,最后官网显示。
2、oracle是活动库,字符集是ZHS16GBK,由于还有很大一部分数据都在oracle库中,所以需要将mysql中的数据同步到oracle中。
3、mysql中有一个字段name,内容是中文、各种火星文。
4、官网是用java开发的,所有项目都是以utf8编码的。
首先需要简单了解几个编码:
1、latin1是ISO-8859-1的别名,ISO-8859-1编码是单字节编码,因此在支持ISO-8859-1的系统中传输和存储其他任何编码的字节流都不会被抛弃。
换言之,把其他任何编码的字节流当作ISO-8859-1编码看待都没有问题。这是个很重要的特性,MySQL数据库默认编码是Latin1就是利用了这个特性。
ASCII编码是一个7位的容器,ISO-8859-1编码是一个8位的容器。
2、gbk,这个就不用说了,汉子的国标码,专门用来表示汉字,是双字节编码,gbk是gb2312的子集,gb2312是gb18030的子集。
3、utf8,这是一个变长编码,它可以使用1~4个字节表示一个符号,根据不同的符号而变化字节长度。
通过java程序解决思路:
1、将从mysql,iso-8859-1查询出来,再转成gbk的编码存储到oracle中,然后再以gbk的方式读出来官网显示。部分显示没有问题,但是gb18030无法显示火星文,很多火星文都显示成?。
2、将从mysql以utf8的编码读出,以utf8的编码存储到oracle中。这部分果断不行,为什么?因为mysql是latin1的编码,以utf8的编码是无法正常读出的,全部是乱码。
3、将mysql以ISO-8859-1的编码读出来,然后转成utf8,再以utf8的编码存储到oracle中。iso无法正常转成utf8,是不兼容的。
以上方法无法正常进行编码转换,只能在汇总数据库这边着手了。如果将汇总mysql的数据库转成utf8的,那么java程序就能正常显示。开始吧!!!
汇总数据库是能正常查看数据库的火星文的,linux支持比java要好多了,可能是由于开源与不开源的问题吧。
1、将数据库进行逻辑备份:
mysqldump --default-character-set=latin1 -q --single-transaction -t db_collect table1 table2 >db_collect.sql
2、重新创建ut8库和表结构
3、通过linux下面的iconv命令进行转码
LANG=en_US
CRT=default
sed -i 's/latin1/utf8/g' db_collect.sql
iconv -f gb18030 -c -t UTF-8 db_collect.sql -o db_collect_result.sql
mysql -f db_collect2 < db_collect_result.sql
4、调整系统编码和CRT编码
LANG=en_US.UTF-8
CRT=UTF-8
5、正常显示数据,通过java程序以utf8的编码方式查看,展示正常。
有个问题,为什么java把latin1的转成gb18030火星文无法显示,在linux下用iconv命令转就可以呢?latin1不能直接转成gb18030,只能以gb18030编码为基础,再转给能够支持火星文的utf8.
显示没有问题了,但是新问题出现了,每次这样转码,会导致数据库无法使用。当然也可以增量进行转码,再导入,不过这样太麻烦了。
最后通过一个php脚本解决问题:直接从上百台数据库以默认的编码查询数据,再通过iconv转成utf8编码,直接insert到utf8表中。
但是这里需要注意的是,在insert前需要set names utf8;系统编码需要改成utf8.
php脚本:
$total_conn = open_mysql($total_mysql[1], $total_mysql[2], $total_mysql[3], $total_mysql[4]);
mysql_query("set names utf8;",$total_conn);
...省略
$total_sql = "insert into db_collect2.table1(name) values ('".iconv('gb18030','UTF-8',$list["name"])."');"
mysql_query($total_sql, $total_conn);
...省略
执行脚本:
export LANG=en_US.UTF-8
php /tmp/collect.php