前段時間在跨版本遷移MySQL數據的時候總是越到亂碼問題,現總結一下。
思想:數據亂碼其實就是數據在寫入時和讀出時使用了不同的字符編碼規則,解決亂碼也就是統一字符編碼規則,也叫統一字符集。比如數據庫表使用ascii編碼存儲數據,而在插入或讀取數據時使用gb2312一定會出亂碼。
在MySQL中字符集是多層繼承的,MySQL默認字符集——>數據庫字符集——>表字符集。在創建數據庫時若未指定數據庫字符集,則新建的庫繼承MySQL默認字符集,同樣,若新建表未指定字符集則繼承所屬的數據庫字符集。在新搭建一臺MySQL服務時一定要提前設定好默認字集,MySQL默認爲latin1,爲了兼容多國語言推薦使用utf8。
查看當前MySQL支持的字符集:
MySQL [(none)]> SHOW charset;
MySQL默認字符集指定方法:
修改my.cnf配置文件:
[mysqld] default-character-set=utf8 #適用於5.1及以前版本 character-set-server=utf8 #適用於5.5版本
檢查當前字符集設置:
SHOW VARIABLES LIKE 'character%';
character_set_client: 客戶端。由配置文件中的default-character-set指定,若不指定則會讀取當前shell終端的字符集,並保持與之保持一直。
character_set_connection:當前連接。當客戶端和服務器字符集不同時以此連接爲準。由配置文件中的default-character-set指定,若不指定則會讀取當前shell終端的字符集,並保持與之保持一直。
character_set_database: 數據庫字符集。由配置文件指定或建庫建表時指定。由服務器端參數character_set_server指定
character_set_filesystem: 字符集文件系統
character_set_results: 返回結果。由配置文件中的default-character-set指定,若不指定則會讀取當前shell終端的字符集,並保持與之保持一直。
character_set_server: 服務器字符集,配置文件指定或建庫建表指定。由服務器端參數character_set_server指定
默認情況下character_set_client、character_set_connection和character_set_results與系統的字符集一致(/etc/sysconfig/i18n)。
查詢數據時亂碼:
1、在查詢數據時亂碼時首先要先查詢出當前數據庫乃至表的當前字符編碼,命令如下:
SHOW CREATE DATABASE DatabaseName; #查詢數據庫編碼規則
SHOW CREATE TABLE DatabaseName.TableName; #查詢表的編碼規則
2、根據庫或表的編碼所用字符集修改SELECT查詢時反饋數據的編碼字符集:
SET NAMES CharacterSet; #設定NAMES值,此命令會同時修改character_set_client、character_set_connection和character_set_results。此設置臨時生效。
或修改my.cnf配置文件:
[client] default-character-set=CharacterSet #配置文件中修改永久生效
插入數據後亂碼:
在拷入數據時同查詢時一樣,首先要保證寫入數據時的編碼同表的編碼規則一致。可通過修改NAMES實現。或使用腳本導入時指定編碼,以gb2312爲例:
SET NAMES gb2312;
或:
mysql --default-character-set=gb2312 DatabaseName < DatabaseName.sql
遷移數據:
若要從一個MySQL服務器中將數據遷移至另一臺MySQL服務器,可通過mysqldump導出數據,將數據拷貝至新服務器後再導入。
1、在導出數據前一定要查看預導出數據庫表的編碼規則:
SHOW CREATE TABLE DatabaseName.TableName;
2、依據該規則指定字符集導出:
mysqldump -hHostIP -uUsername -p --default-character-set=CharacterSet DatabaseName > DatabaseName.sql
3、數據拷貝至新服務器後,在導入時指定新數據庫表的字符集:
mysql --default-character-set=NewCharacterSet DatabaseName < DatabaseName.sql
注意:
1)在新MySQL服務器中導入數據前要注意檢查DatabaseName.sql腳本文件中指定的存儲引擎和字符集是否與新服務器一致,若不一致可使用sed命令修改;
2)mysqldump導出的腳本文件中沒有新建數據庫,需要提前手工創建數據庫,並在導入時指定該數據庫;
Example:
mysqldump --default-character-set=binary jicheng > binary-jicheng.sql scp binary-jicheng.sql [email protected]:/media/data/importing/wwwDB/jicheng/ sed -i 's/ ENGINE=MyISAM DEFAULT CHARSET=latin1//g' binary-jicheng.sql
CREATE DATABASE jicheng DEFAULT CHARACTER SET gb2312; SHOW CREATE DATABASE jicheng;
mysql --default-character-set=gb2312 jicheng < binary-jicheng.sql
--需存儲爲utf8,需再次導出數據,並在創建表時指定DEFAULT CHARSET=utf8