一.字符編碼概述:
從本質(zhì)上來說,計(jì)算機(jī)只能識(shí)別二進(jìn)制代碼,因此,不論是計(jì)算機(jī)程序還是其他被處理的數(shù)據(jù),最終都必須轉(zhuǎn)換成二進(jìn)制,計(jì)算機(jī)
才能認(rèn)識(shí)。為了使計(jì)算機(jī)不僅能做科學(xué)計(jì)算,也能處理文字信息,人們想出了給每個(gè)文字符號(hào)編碼以便于計(jì)算機(jī)識(shí)別處理,這就是計(jì)算
機(jī)字符集的由來。簡單的說字符集就是一套文字符號(hào)及編碼、比較規(guī)則的集合。
20世紀(jì)60年代初期,美國標(biāo)準(zhǔn)化組織ANSI發(fā)布了第一個(gè)計(jì)算機(jī)字符集ASCII(American Standard Code for Information Interchange,
美國信息交換標(biāo)準(zhǔn)碼),后來進(jìn)一步變成了國際標(biāo)準(zhǔn)ISO-646,這個(gè)字符集采用7位編碼,定義了包括大小寫英文字母、阿拉伯?dāng)?shù)字和標(biāo)
點(diǎn)符號(hào),以及33個(gè)控制符號(hào)等。雖然現(xiàn)在看來,這個(gè)美式的字符集很簡單,包括的符號(hào)也很少,但是直到今天它依然是計(jì)算機(jī)世界里奠
定性的標(biāo)準(zhǔn),其后制定的各種字符集基本都兼容ASCII字符集。
自從ASCII之后,為了處理不同的文字,各大計(jì)算機(jī)公司、各國***、標(biāo)準(zhǔn)化組織等先后發(fā)明了幾百種字符集,比如我們熟悉的
ISO-8859系列、GB2312-80、GBK、BIG5等。這些五花八門的字符集,從收錄的字符到編碼規(guī)則各不相同,給計(jì)算機(jī)軟件開發(fā)和移植帶來
了很大的困難。一個(gè)軟件要在使用的不同文字的國家或地區(qū)發(fā)布,必須進(jìn)行本地化開發(fā)!基于這個(gè)原因,統(tǒng)一字符編碼,成了20世紀(jì)80
年代計(jì)算機(jī)業(yè)的迫切需要和普遍共識(shí)。
為了統(tǒng)一字符編碼,國際標(biāo)準(zhǔn)化組織ISO(International Standardization Organization)的一些成員國于1984年發(fā)起新的國際
字符集標(biāo)準(zhǔn),以容納全世界各種語言文字和符號(hào)。這個(gè)標(biāo)準(zhǔn)最后叫做通用字符集(Universal Character Set,簡稱UCS),標(biāo)準(zhǔn)編號(hào)為
ISO-10646。ISO-10646標(biāo)準(zhǔn)采用4個(gè)字節(jié)編碼,因此簡稱UCS-4。
ISO-10646標(biāo)準(zhǔn)發(fā)布之后,遭到了部分美國計(jì)算機(jī)公司的反對。1988年Xerox公司提議制定新的以2個(gè)字節(jié)編碼的統(tǒng)一字符集Unicode,
并聯(lián)合Apple、IBM、DEC、Sun、Microsoft、Novell等公司成立Unicode協(xié)會(huì),并成立Unicode技術(shù)委員會(huì),專門負(fù)責(zé)Unicode文字的收集、
整理和編碼,并與1991年推出了Unicode1.0
那么問題來了,ISO和Unicode協(xié)會(huì)推出了兩個(gè)不同的編碼標(biāo)準(zhǔn),這顯然是不利的。后來大家都認(rèn)識(shí)到了這一點(diǎn),經(jīng)過雙發(fā)談判,
1991年10月達(dá)成協(xié)議,ISO將Unicode編碼并入ISO-10646標(biāo)準(zhǔn)里面。此時(shí)ISO-10646其實(shí)包括
基本多語言文字面(BMP,也就是并入的Unicode編碼)、
輔助字面、專用字面,
其中輔助字面用以收錄ISO-10646后續(xù)收集的各國文字,專用字面供使用者自定義收錄ISO-10646未收錄的
文字符號(hào)。其實(shí),大部分用戶只使用BMP字面就足夠了,早期的ISO-10646-1標(biāo)準(zhǔn)也只要求實(shí)現(xiàn)BMP字面部分即可,這樣只需要2個(gè)字節(jié)(簡稱UCS-2編碼)
來編碼就足夠了,UCS-2編碼轉(zhuǎn)換成UCS-4編碼也很容易,只要在前面加兩個(gè)取值為0的字節(jié)即可!
ISO-10646標(biāo)準(zhǔn)的編碼空間足以容納人類從古至今使用過得所有文字和符號(hào),但其實(shí)許多文字符號(hào)否已經(jīng)很少使用,超過99%的在用
文字符號(hào)都編入了ISO-10646里面的BMP(基本多語言文字面)部分,所以絕大部分情況下,Unicode的雙字節(jié)編碼方式都能滿足需求,而
這種雙字節(jié)編碼方式比起ISO-10646的4字節(jié)原始編碼來說,在節(jié)省內(nèi)存和處理時(shí)間上都具有優(yōu)勢,這也是Unicode編碼方式更流行的原因。
但是如果萬一碰到要使用ISO-10646 BMP字面以外的文字怎么辦呢?Unicode提出了名為UTF-16或代理法的解決方案,
UTF是UCS/Unicode Transformation Format的縮寫。但是當(dāng)時(shí)的計(jì)算機(jī)和網(wǎng)絡(luò)世界還是ASCII的天下,只能處理單字節(jié)流,
UTF-16在離開Unicode環(huán)境后,在傳輸和處理中都存在問題,于是Unicode又提出了名為UTF-8的解決方案。
ISO-10646與Unicode統(tǒng)一以后,兩個(gè)組織雖然都繼續(xù)發(fā)布各自的標(biāo)準(zhǔn),但二者之間是一致的。由于Unicode最早投入應(yīng)用,其編碼方
式更加普及,因此許多人都知道Unicode,但對ISO-10646卻了解不多。但是由于兩者是一致的,因此根本不需要區(qū)分兩者了,對于現(xiàn)在
來說Unicode和ISO-10646,一般指的是同一個(gè)東西!
兩者不同版本的對應(yīng)關(guān)系:
Unicode2.0等同于ISO/IEC 10646-1:1993
Unicode3.0等同于ISO/IEC 10646-1:2000
Unicode4.0等同于ISO/IEC 10646:2003
二、漢字常見字符集
在計(jì)算機(jī)發(fā)展的不同階段,我國也參照當(dāng)時(shí)的國際標(biāo)準(zhǔn)和實(shí)際需要,制定了一些漢字字符集編碼標(biāo)準(zhǔn)
1.GB2312-80:
即GB2312,是中華人民共和國國家標(biāo)準(zhǔn)簡體中文字符集,全稱《信息交換用漢字編碼字符集 基本集》,1980年發(fā)布,1981年5月1日實(shí)施。
GB2312編碼通行于中國大陸,中國大陸幾乎所有的中文系統(tǒng)和國際化的軟件都支持GB 2312
2.GBK:
漢字內(nèi)碼擴(kuò)展規(guī)范,發(fā)布于1995年,在GB2312的基礎(chǔ)上做了擴(kuò)充,且對GB2312完全兼容,但是GBK并不是一個(gè)強(qiáng)制性的國家標(biāo)準(zhǔn),只是一個(gè)
行業(yè)指導(dǎo)規(guī)范,并沒有強(qiáng)制力,但是由于得到了微軟windows95的支持而大為流行
三、國際編碼UTF-8
是一種針對Unicode的可變長度字符編碼,通用性很好。
四、常用字符集比較
ACSII:單字節(jié)7位編碼,最早的奠定性字符集
ISO-8859-1/latin1:單字節(jié)8位編碼,西歐字符集
GB2312-80:雙字節(jié)編碼,早期標(biāo)準(zhǔn)
GBK:雙字節(jié)編碼,雖然不是國標(biāo)但是支持的系統(tǒng)很多
UTF-32:4個(gè)字節(jié)編碼,UCS-4原始編碼,目前很少采用
UCS-2:2字節(jié)編碼,windows2000內(nèi)部用UCS-2
UTF-16:2字節(jié)或4字節(jié)編碼,Java和Windows XP/NT等內(nèi)部使用UTF-16
UTF-8:1~4字節(jié)編碼,互聯(lián)網(wǎng)和Unix/Linux廣泛支持的Unicode字符集,UTF-8漢字編碼需要使用3個(gè)字節(jié)
五、MySQL支持的字符集
1.查看所有可用的字符集
show character set;
或者查看information_schema.character_sets,也可以顯示所有的字符集和該字符集默認(rèn)的校隊(duì)規(guī)則
2.MySQL的字符集包括字符集(character)和校對規(guī)則(collation)兩個(gè)概念。
1)字符集用來定義MySQL存儲(chǔ)字符串的方式
2)校對規(guī)則用來定義 字符串比較的方式
3)字符集和校對規(guī)則是一對多的關(guān)系,一個(gè)字符集有多個(gè)校對規(guī)則供你選擇!
校對規(guī)則命名約定:它們以相關(guān)的字符集名開始,通常包括一個(gè)語言名,并且以
_ci(忽略大小寫)、
_cs(大小寫敏感)或者
_bin(二元,即比較是基于字符編碼的值而與language無關(guān))結(jié)束。
查看字符集的校對規(guī)則:
show collation like '字符集前綴%';
六、MySQL內(nèi)部的字符集和校對規(guī)則設(shè)置
MySQL內(nèi)部的字符集和校對規(guī)則有4個(gè)級別的默認(rèn)設(shè)置:服務(wù)器級、數(shù)據(jù)庫級、表級和字段級
1.服務(wù)器字符集和校對規(guī)則設(shè)置
1)在配置文件中設(shè)置
[mysqld]
character-set-server=utf8
2)或者在啟動(dòng)項(xiàng)中指定
mysqld --character-set-server=utf8
3)或者在編譯的時(shí)候指定
2.數(shù)據(jù)庫字符集和校對規(guī)則設(shè)置
數(shù)據(jù)庫的字符集和校對規(guī)則在創(chuàng)建數(shù)據(jù)庫的時(shí)候指定,也可以在創(chuàng)建完數(shù)據(jù)庫后通過alter database命令修改.需要注意的是如果數(shù)據(jù)庫里已經(jīng)有數(shù)據(jù)存在,因?yàn)樾薷淖址⒉荒軐?br/> 已有的數(shù)據(jù)按照新的字符集進(jìn)行存放,所以不能通過修改數(shù)據(jù)庫的字符集直接修改數(shù)據(jù)的內(nèi)容,需要重新導(dǎo)出,然后修改字符編碼再導(dǎo)入來解決!
設(shè)置數(shù)據(jù)庫字符集的規(guī)則如下:
1)如果指定了字符集和校對規(guī)則,則使用指定的字符集和校對規(guī)則
2)如果指定了字符集沒有指定校對規(guī)則,則使用指定字符集的默認(rèn)校對規(guī)則
3)如果指定了校對規(guī)則但未指定字符集,則使用與該校對規(guī)則關(guān)聯(lián)的字符集
4)如果沒有指定字符集和校對規(guī)則,則使用服務(wù)器字符集和校對字符集和校對規(guī)則作為數(shù)據(jù)庫的字符集和校對規(guī)則
CREATE DATABASE db_name
[[DEFAULT] CHARACTER SET charset_name]
[[DEFAULT] COLLATE collation_name]
ALTER DATABASE db_name
[[DEFAULT] CHARACTER SET charset_name]
[[DEFAULT] COLLATE collation_name]
查看當(dāng)前數(shù)據(jù)庫的字符集和校對規(guī)則:
show variables like 'character_set_database';
show variables like 'collation_database';
3.表字符集和校對規(guī)則設(shè)置
表的字符集和校對規(guī)則在創(chuàng)建表的時(shí)候指定,也可以通過alter table 命令進(jìn)行修改,同樣的是如果表中已經(jīng)有數(shù)據(jù)那么修改字符集對原來的記錄并沒有影響,不會(huì)按照新的字符集進(jìn)行存放!
設(shè)置表字符集的規(guī)則如下:
1)如果指定了字符集和校對規(guī)則,則使用指定的字符集和校對規(guī)則
2)如果指定了字符集沒有指定校對規(guī)則,則使用指定字符集的默認(rèn)校對規(guī)則
3)如果指定了校對規(guī)則但未指定字符集,則使用與該校對規(guī)則關(guān)聯(lián)的字符集
4)如果沒有指定字符集和校對規(guī)則,則使用數(shù)據(jù)庫字符集和校對字符集和校對規(guī)則作為表的字符集和校對規(guī)則
CREATE TABLE tbl_name (column_list)
[DEFAULT CHARACTER SET charset_name [COLLATE collation_name]]
ALTER TABLE tbl_name
[DEFAULT CHARACTER SET charset_name] [COLLATE collation_name]
4.字段(列)字符集和校對規(guī)則
遇到這種情況概率比較小,這只是MySQL提供給我們一個(gè)靈活設(shè)置的手段
七、MySQL連接字符集設(shè)置
連接字符集設(shè)置:客戶端和服務(wù)器之間交互的字符集
1.對于客戶端和服務(wù)器段的交互***作,MySQL提供了3個(gè)不同的參數(shù):
1)character_set_client:客戶端來源數(shù)據(jù)使用的字符集
2)character_set_connection:連接層字符集
3)character_set_results:返回結(jié)果字符集
知識(shí)拓展:數(shù)據(jù)在客戶端和服務(wù)器之間交互的過程中字符集轉(zhuǎn)換的大概過程
1) MySQL Server收到請求時(shí)將請求數(shù)據(jù)從character_set_client轉(zhuǎn)換為character_set_connection;
2) 進(jìn)行內(nèi)部***作前將請求數(shù)據(jù)從character_set_connection轉(zhuǎn)換為內(nèi)部***作字符集,內(nèi)部***作字符集的確定方法如下:
1>使用每個(gè)數(shù)據(jù)字段設(shè)定的字符集;
2>若上述值不存在,則使用對應(yīng)數(shù)據(jù)表設(shè)定的字符集;
3>若上述值不存在,則使用對應(yīng)數(shù)據(jù)庫設(shè)定的字符集;
4>若上述值不存在,則使用服務(wù)器設(shè)定的字符集。
3) 將***作結(jié)果從內(nèi)部***作字符集轉(zhuǎn)換為character_set_results。
這3個(gè)參數(shù)設(shè)定的字符集應(yīng)該相同,并且客戶端使用的字符集確實(shí)是參數(shù)character_set_client的值,才可以確保用戶的數(shù)據(jù)可以正確的返回且輸出。
查看當(dāng)前設(shè)置:show variables like 'character_set%';
修改:
set names 字符集,可以同時(shí)修改3個(gè)參數(shù)的值,對本次有效
也可以在配置文件中設(shè)置:
[mysql]
default-character-set=字符集
修改CMD命令行字符集:
chcp 65001 #換成utf-8代碼頁(設(shè)置為utf-8之后最好手動(dòng)修改顯示字體 )
chcp 936 #換成默認(rèn)的gbk
微信掃碼
關(guān)注PHP中文網(wǎng)服務(wù)號(hào)
QQ掃碼
加入技術(shù)交流群
Copyright 2014-2025 http://ipnx.cn/ All Rights Reserved | php.cn | 湘ICP備2023035733號(hào)