在安装mysql时可能根据不同需要会设置mysql服务器不同的字符集了,但今天小编碰到一个问题就是要把latin1迁移utf8了,下面找到了一篇关于mysql字符集latin1迁移utf8的方法,下面一起来看看.
场景说明:
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-fgb18030-c-tUTF-8db_collect.sql-odb_collect_result.sql
- mysql-fdb_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("setnamesutf8;",$total_conn);
- ...省略
- $total_sql="insertintodb_collect2.table1(name)values('".iconv('gb18030','UTF-8',$list["name"])."');"//phpfensi.com
- mysql_query($total_sql,$total_conn);
- ...省略
- 执行脚本:
- exportLANG=en_US.UTF-8
- php/tmp/collect.php