在安裝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 -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"])."');" //Vevb.com
- mysql_query($total_sql, $total_conn);
- ...省略
- 執行腳本:
- export LANG=en_US.UTF-8
- php /tmp/collect.php
新聞熱點
疑難解答