【mysql】字符集迁移-latin1到utf8
时间:2015-01-10 10:01:42 作者:beebol 标签: icovn latin1 mysql uft8 分类: mysql
场景说明:
1、现上几百台mysql数据库,字符编码latin1,现在需要做一个活动,将现上mysql数据库的一些活动数据同步到一台mysql汇总数据库(latin1),然后再将数据同步oracle中,最后官网显示。 2、oracle是活动库,字符集是ZHS16GBK,由于还有很大一部分数据都在oracle库中,所以需要将mysql中的数据同步到oracle中。 3、mysql中有一个字段name,内容是中文、各种火星文。4、官网是用java开发的,所有项目都是以utf8编码的。 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个字节表示一个符号,根据不同的符号而变化字节长度。 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程序就能正常显示。开始吧!!! 以上方法无法正常进行编码转换,只能在汇总数据库这边着手了。如果将汇总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-8php /tmp/collect.php php /tmp/collect.php