MySQL伴隨著我已有四五年了,在使用MySQL的過(guò)程中,也碰到過(guò)字符編碼問(wèn)題(亂碼)。
在Google中搜索“mysql 亂碼”,可以查到“429,000”條結(jié)果;搜索“jsp 亂碼”,可以查到“335,000”條結(jié)果,當(dāng)然JSP亂碼不一定就是MySQL亂碼,但多數(shù)情況是編碼問(wèn)題(可能是頁(yè)面編碼、數(shù)據(jù)庫(kù)編碼)。
可見(jiàn),編碼問(wèn)題在我們開(kāi)發(fā)過(guò)程中是經(jīng)常出現(xiàn)的,因此對(duì)編碼的了解、設(shè)置和修改就顯得及其重要了。
今天對(duì)MySQL邊學(xué)習(xí)邊查資料特意整理總結(jié)本文,以作備份,希望給各網(wǎng)友參考,一起學(xué)習(xí)討論。
一、MySQL字符集和校對(duì)規(guī)則
我們都知道,字符集就是一套文字符號(hào)及其編碼、比較規(guī)則的集合,因?yàn)橛?jì)算機(jī)只認(rèn)識(shí)二進(jìn)制代碼,所有我們必須要有一個(gè)轉(zhuǎn)換。
MySQL的字符集包括字符集(Character Set)和校對(duì)規(guī)則(Collation)兩個(gè)概念。字符集是用來(lái)定義MySQL存儲(chǔ)字符串的方式,而校對(duì)規(guī)則則定義了比較字符串的方式。
字符集和校對(duì)規(guī)則是一對(duì)多的關(guān)系,每個(gè)字符集至少對(duì)應(yīng)一個(gè)校對(duì)規(guī)則,稱為默認(rèn)校對(duì)規(guī)則。
查看所有字符集的命令:show character set;
或是查看information_schema.character_sets,可以得到所有的字符集和它的默認(rèn)的校對(duì)規(guī)則,它的表結(jié)構(gòu):desc information_schema.character_sets;
查看字符集的校對(duì)規(guī)則:show collation like 'GBK%';
校對(duì)規(guī)則命名約定:以其相關(guān)的字符集名開(kāi)始,通常包括一個(gè)語(yǔ)言名,并且以_ci(大小寫(xiě)不敏感)、_cs(大小寫(xiě)敏感)或_bin(二元,即比較是基于字符編碼的值而與語(yǔ)言無(wú)關(guān))結(jié)束。
實(shí)驗(yàn)命令:
select case when 'A' COLLATE utf8_general_ci = 'a' COLLATE utf8_general_ci then 'YES' else 'NO' end;(YES)
select case when 'A' COLLATE gbk_chinese_ci = 'a' COLLATE gbk_chinese_ci then 'YES' else 'NO' end;(YES)
select case when 'A' COLLATE gbk_bin = 'a' COLLATE gbk_bin then 'YES' else 'NO' end;(NO)
二、設(shè)置字符集
MySQL的字符集和校對(duì)規(guī)則有4個(gè)級(jí)別的默認(rèn)設(shè)置:服務(wù)器級(jí)、數(shù)據(jù)庫(kù)級(jí)、表級(jí)和字段級(jí)。
服務(wù)器級(jí):
[mysqld]
default-character-set=utf8
[mysql]
default-character-set=utf8
或是啟動(dòng)時(shí)加上參數(shù):mysqld --default-character-set=utf8
或是編譯時(shí)加上參數(shù):./configure --width-charset=utf8
查看字符集和校對(duì)規(guī)則:
show variables like 'character_set_server';
show variables like 'collation_server';
數(shù)據(jù)庫(kù)級(jí):
查看字符集和校對(duì)規(guī)則:
show variables like 'character_set_database';
show variables like 'collation_database';
表級(jí):
查看字符集和校對(duì)規(guī)則:
show create table t \G
四、簡(jiǎn)單修改字符集
簡(jiǎn)單修改只對(duì)以后的數(shù)據(jù)有影響,如果數(shù)據(jù)庫(kù)中沒(méi)有數(shù)據(jù)或是不想修改以前的數(shù)據(jù),可以使用簡(jiǎn)單修改。
簡(jiǎn)單修改命令:
alter database character set utf8;
alter table t character set utf8;
個(gè)人推薦在創(chuàng)建數(shù)據(jù)庫(kù)時(shí)明確指定字符集和校對(duì)規(guī)則,避免受到默認(rèn)值的影響。
創(chuàng)建數(shù)據(jù)庫(kù)時(shí)指定:
create database databasename default charset GBK;
創(chuàng)建數(shù)據(jù)表時(shí)指定:
create table tablename(
....
) ENGIND=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin;
五、完全修改字符集
當(dāng)數(shù)據(jù)庫(kù)中已有數(shù)據(jù),想修改數(shù)據(jù)集,不能通過(guò)簡(jiǎn)單的修改字符集完成,需要先將原數(shù)據(jù)導(dǎo)出,經(jīng)過(guò)適當(dāng)調(diào)整后重新導(dǎo)入才可完成。
通過(guò)七步完成字符集的完全修改(假設(shè)原字符集是latin1,想修改成GBK)。
1、導(dǎo)出表結(jié)構(gòu):
mysqldump -uroot -p --default-character-set=GBK -d databasename>createdb.sql
說(shuō)明:
--default-character-set=GBK 表示設(shè)置以什么字符集連接;
-d 表示只導(dǎo)出表結(jié)構(gòu),不導(dǎo)出數(shù)據(jù)。
2、手工修改createdb.sql中表結(jié)構(gòu)定義中的字符集(latin1)為新的字符集(GBK);
3、確保數(shù)據(jù)庫(kù)中的數(shù)據(jù)不再更新,導(dǎo)出所有的數(shù)據(jù):
mysqldump -uroot -p --quick --no-create-info --extended-insert --default-character-set=latin1 databasename>data.sql
說(shuō)明:
--quick 該選項(xiàng)用于轉(zhuǎn)儲(chǔ)大的表,它強(qiáng)制mysqldump從服務(wù)器一次一行地檢索表中的行而不是檢索所有行,并在輸出前將它緩存到內(nèi)存中;
--extended-insert 使用包括幾個(gè)values的多行insert語(yǔ)法;
--no-create-info 不要create table語(yǔ)句;
--default-character-set=latin1 表示按照原有的字符集導(dǎo)出所有的數(shù)據(jù)。
4、打開(kāi)data.sql,將set names latin1修改成set names GBK;
5、使用新的字符集創(chuàng)建數(shù)據(jù)庫(kù):
create database databasename default charset GBK;
6、創(chuàng)建表:
mysql -uroot -p databasename < createdb.sql
7、導(dǎo)入數(shù)據(jù):
mysql -uroot -p databasename < data.sql
六、最后
建議服務(wù)器的字符集參數(shù)不要修改,而是是創(chuàng)建數(shù)據(jù)庫(kù)進(jìn)加上字符集,特別是在創(chuàng)建表時(shí)記得加上,這樣做的目的是為了使修改的影響最小化。
[ 本帖最后由 happyfan 于 2010-6-29 14:48 編輯 ]