MySQL--字符集
生活随笔
收集整理的這篇文章主要介紹了
MySQL--字符集
小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
1.字符集概述
- 簡單的說字符集就是一套文字符號(hào)及其編碼、比較規(guī)則的集合
- 20世紀(jì)60年代初期,美國標(biāo)準(zhǔn)化組織ANSI發(fā)布了第一個(gè)計(jì)算機(jī)的字符集ASCII(American Standard Code for Information Interchange),后來進(jìn)一步變成了國際標(biāo)準(zhǔn)ISO-646。這個(gè)字符集采用7位編碼,定義了包括大小寫英文字母、阿拉伯?dāng)?shù)字和標(biāo)點(diǎn)符號(hào),以及33個(gè)控制符號(hào)等。
2.Unicode簡述
- 為了統(tǒng)一字符編碼,國際標(biāo)準(zhǔn)化組織ISO(International Organization for Standardization)的一些成員國于1984年發(fā)起制定新的國際字符集標(biāo)準(zhǔn),以容納全世界各種語言文字和符號(hào)。這個(gè)標(biāo)準(zhǔn)最后叫做Universal Multiple-Octet Coded Character Set,簡稱UCS,標(biāo)準(zhǔn)編號(hào)則定位ISO-10646。ISO-10646標(biāo)準(zhǔn)采用4字節(jié)(32bit)編碼,因此簡稱UCS-4。
- ISO-10646發(fā)布以后,遭到了部分美國計(jì)算機(jī)公司的反對(duì)。1988年Xerox公司提議指定新的以16為編碼的統(tǒng)一字符集Unicode,并聯(lián)合Apple, IBM, DEC, Sun, Microsoft, Novell等公司成立Unicode協(xié)會(huì)(The Unicode Consortium),并成立Unicode技術(shù)委員會(huì)(Unicode Technical Committee),專門負(fù)責(zé)Unicode文字的搜集、整理合編碼,并于1991年推出了Unicode 1.0
- 1991年10月,ISO將Unicode編碼并入ISO-10646的0組0字面,叫做基本多語言文字面(Basic Muiti-lingual Plane,BMP),共有65534個(gè)碼位,并根據(jù)不同用途分為若干區(qū)域。除BMP外的32767個(gè)字面又分為輔助字面和專用字面兩部分,輔助字面用以收錄IS0-10646后續(xù)搜集的各國文字,專用字面供使用者自定義收錄ISO-10646未收錄的文字符號(hào)。大部分用戶只是用BMP字面就足夠了,早期的ISO-10646標(biāo)準(zhǔn)也只要求實(shí)現(xiàn)BMP字面,這樣只需要2字節(jié)來編碼就足夠了,Unicode也正是這么做的,這叫做ISO-10646編碼的基本面形式,簡稱為UCS-2編碼,UCS-2編碼轉(zhuǎn)換成UCS-4編碼也很容易,只要在前面加兩個(gè)取值為0的字節(jié)即可
- Unicode雙字節(jié)編碼方式比起ISO-10646的4字節(jié)原始編碼來說,在節(jié)省內(nèi)存和處理時(shí)間上都具有優(yōu)勢(shì),這也是Unicode編碼方式更流行的原因。如果需要使用ISO-10646 BMP字面意外的文字,Unicode提出了名為UTF-16或代理法的解決方案,UTF是UCS/Unicode Transformation Format的縮寫。UTF-16的解決辦法是:對(duì)BMP字面的編碼保持二字節(jié)不變,對(duì)其他字面的文字按一定規(guī)則將其32位編碼轉(zhuǎn)換為兩個(gè)16位的Unicode編碼,供兩個(gè)字節(jié)的取值范圍分別限定為0XD800~0xDBFF和0xDC00~0xDFFF,因此,UTF-16共有( 4 * 256 ) * ( 4 ?* 256 ) = 1048576 個(gè)碼位
- 雖然UTF-16解決了ISO-10646除BMP外第1~15字面的編碼問題,但當(dāng)時(shí)的計(jì)算機(jī)和網(wǎng)絡(luò)還是ASCII的天下,只能處理單字節(jié)數(shù)據(jù)流,UTF-16在離開Unicode環(huán)境后,在傳輸和處理中都存在問題。于是Unicode又提出了名為UTF-8的解決方案,UTF-8按一定規(guī)則將一個(gè)ISO-10646或Unicode字元碼轉(zhuǎn)換成1~4個(gè)字節(jié)的編碼,其中將ASCII碼(0~0x7F)轉(zhuǎn)換成單字節(jié)編碼,也就是嚴(yán)格兼容ASCII字符集;UTF-8的2字節(jié)編碼,用以轉(zhuǎn)換ISO-10646標(biāo)準(zhǔn)0x0080~0x07FF的UCS-4原始碼;UTF-8的3字節(jié)編碼,用以轉(zhuǎn)換ISO-10646標(biāo)準(zhǔn)0x0800~0xFFFF的UCS-4原始碼;UTF-8的4字節(jié)編碼,用以轉(zhuǎn)換ISO-10646標(biāo)準(zhǔn)0X00010000~0001FFFF的UCS-4原始碼。
- ISO-10646只是給每一個(gè)文字符號(hào)分配了一個(gè)4字節(jié)無符號(hào)整數(shù)編號(hào)(UCS-4),并未規(guī)定在計(jì)算機(jī)中如何去表示這個(gè)無符號(hào)的整數(shù)編號(hào)。UTF-16和UTF-8就是其兩種變通表示方式。
- 現(xiàn)在,Unicode和ISO-10646一般指的是同一個(gè)東西
- UTF-16和UTF-32因字節(jié)序的不同,又有了UTF-16BE(B一個(gè)Endian), UTF-16LE(Little Endian), UTF-32BE(Big Endian), UTF-32LE(Little Endian)等
?
3.漢字及一些常見的字符集
- GB 2312-80:全稱《信息交換用漢字編碼字符集 基本集》,于1980年發(fā)布。根據(jù)ISO/IEC 2022提供的字符編碼擴(kuò)充規(guī)范,形成雙字節(jié)編碼的字符集。收錄了常用漢字6763個(gè)和非漢字圖形符號(hào)682個(gè)
- GB13000:全稱《信息技術(shù) 通用多八位編碼字符集(UCS) 第一部分:體系結(jié)構(gòu)與基本多文種平面》,于1993年發(fā)布、根據(jù)ISO/IEC 10646-1:1993,在CJK(中日韓簡稱)統(tǒng)一漢字區(qū)和CJK統(tǒng)一漢字?jǐn)U充區(qū)A,除收錄GB 2312-80外,還收錄了第1,3,5,7輔助集的全部漢字,宮27474個(gè),以及一些偏旁部首等。但GB13000退出后,幾乎沒有得到業(yè)界的支持,也就成了一個(gè)形式上的標(biāo)準(zhǔn)
- GBK:全稱《漢字內(nèi)碼擴(kuò)展規(guī)范》 1.0版,發(fā)布于1995年。GBK在GB2312內(nèi)碼系統(tǒng)上進(jìn)行了擴(kuò)充,收錄了GB 13000.1-1993的全部20902個(gè)CJK統(tǒng)一漢字,包括GB2312的全部6763個(gè)漢字。此外,他增補(bǔ)編碼了52個(gè)漢字,13個(gè)漢字結(jié)構(gòu)符(在ISO/IEC 10646.1:2000中稱為表意文字描述符)和一些常用部首與漢字部件。在GBK內(nèi)碼系統(tǒng)中,GB 2312漢字所在碼位保持不變,這樣,保證了GBK對(duì)GB 2312的完全兼容。同時(shí),GBK內(nèi)碼與GB13000.1代碼一一對(duì)應(yīng),為GBK向GB 13000.1的轉(zhuǎn)換提供了解決辦法。有意思的是GBK并不是一個(gè)強(qiáng)制性的國家標(biāo)準(zhǔn),只是一個(gè)行業(yè)指導(dǎo)規(guī)范,并沒有強(qiáng)制力,但由于得到了Microsoft Windows95的支持而大為流行
- GB 18030:全稱《信息技術(shù)信息交換用漢字編碼字符集、基本集的擴(kuò)充》,發(fā)布于2000年。根據(jù)ISO/IEC 10646-1:2000,收錄了ISO/IEC 10646.1:2000全部27848個(gè)CJK統(tǒng)一漢字,13個(gè)表意文字描述符、部分漢字部首和部件、歐元符號(hào)等。GB 18030采用2字節(jié)或4字節(jié)編碼,其二字節(jié)編碼部分與GBK保持一致,因此,GB18030SHI GBK的超集,也完全與GB 13000向上兼容,制定GB 18030也是為了解決GBK強(qiáng)制力不夠的問題
?
常用字符集比較
| 字符集 | 是否定長 | 編碼方式 | 其他說明 |
| ASCII | 是 | 單字節(jié)7位編碼 | 最早的奠基性字符集 |
| ISO-8859-1/latin1 | 是 | 單字節(jié)8位編碼 | 西歐字符集,經(jīng)常被一些程序員用來轉(zhuǎn)碼 |
| GB 2312-80 | 是 | 雙字節(jié)編碼 | 早起標(biāo)準(zhǔn),不推薦再使用 |
| GBK | 是 | 雙字節(jié)編碼 | 雖然不是國標(biāo),但支持的系統(tǒng)不少 |
| GB 18030 | 否 | 2字節(jié)或4字節(jié)編碼 | 開始有一些支持,但數(shù)據(jù)庫支持的還少見 |
| UTF-32 | 是 | 4字節(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字符集;MySQLServer也使用UTF-8 |
?
?
4.選擇合適的字符集
- 對(duì)數(shù)據(jù)庫來說,字符集更加重要,因?yàn)閿?shù)據(jù)庫存儲(chǔ)的數(shù)據(jù)大部分都是各種文字,字符集對(duì)數(shù)據(jù)庫的存儲(chǔ)、處理性能,以及日后系統(tǒng)的移植、推廣都會(huì)有影響
- MySQL目前支持幾十種字符集,包括UCS-2, UTF-16, UTF-16TE, UTF-32, UTF-8和utfmb64等Unicode字符集
- 滿足應(yīng)用支持語言的需求,如果應(yīng)用要處理各種各樣的文字,或者將發(fā)布到使用不同漢語言的國家和地區(qū),就應(yīng)該選擇Unicode字符集、對(duì)MySQL來說,目前就是UTF-8
- 如果應(yīng)用中涉及已有數(shù)據(jù)的導(dǎo)入,就要充分考慮數(shù)據(jù)庫字符集對(duì)已有數(shù)據(jù)的兼容性。
- 如果數(shù)據(jù)庫只需要支持一般中文數(shù)據(jù)量很大,性能要求也很高,那就應(yīng)該選擇雙字節(jié)定長編碼的中文字符集,比如GBK。因?yàn)閷?duì)UTF-8而言,GBK比較小,每個(gè)漢字只占2個(gè)字節(jié),而UTF-8漢字編碼需要3個(gè)字節(jié),這樣可以減少磁盤I/O、數(shù)據(jù)庫Cache以及網(wǎng)絡(luò)傳輸?shù)臅r(shí)間,從而提高性能。相反,如果應(yīng)用主要處理英文字符,僅有少量漢字?jǐn)?shù)據(jù),那么選擇UTF-8更好,因?yàn)镚BK、UCS-2、UTF-16的西文字符編碼都是2個(gè)字節(jié),會(huì)造成很多不必要的開銷
- 如果數(shù)據(jù)庫需要做大量的字符運(yùn)算,如比較、排序等,那么選擇定長字符集可能更好,因?yàn)槎ㄩL字符集的處理速度要比變長字符集的處理速度快
- 如果所有客戶端程序都支持相同的字符集,則應(yīng)該優(yōu)先選擇該字符集作為數(shù)據(jù)庫字符集,這樣可以避免因字符集轉(zhuǎn)換帶來的性能開銷和數(shù)據(jù)損失
?
5.MySQL支持的字符集簡介
- MySQL服務(wù)器可以支持多種字符集,在同一臺(tái)服務(wù)器、同一個(gè)數(shù)據(jù)庫甚至同一個(gè)表的不同字段都可以指定使用不同的字符集,相比Oracle等其他數(shù)據(jù)庫管理系統(tǒng),在同一個(gè)數(shù)據(jù)庫只能使用相同的字符集,MySQL明顯存在很大的靈活性。
- 查看所有可用的字符集的命令
SHOW CHARACTER SET - 顯示所有的字符集和該字符集默認(rèn)的校對(duì)規(guī)則
DESC information_schema.character_set - MySQL的字符集包括字符集(CHARACTER)和校對(duì)規(guī)則(COLLAION)兩個(gè)概念。其中字符集用來定義MySQL存儲(chǔ)字符串的方式,校對(duì)規(guī)則用來定義比較字符串的方式。字符集和校對(duì)規(guī)則是一對(duì)多的關(guān)系,MySQL支持30多種字符集的70多種校對(duì)規(guī)則。每個(gè)字符集至少對(duì)應(yīng)一個(gè)校對(duì)規(guī)則,可以用
SHOW COLLATION LIKE '***'
或通過表 information_schema.COLLATIONS來查看相關(guān)字符集的校對(duì)規(guī)則
校對(duì)規(guī)則命名約定:他們以其相關(guān)的字符集名開始,通常包括一個(gè)語言名,并且以_ci(大小寫不敏感),_cs(大小寫敏感),_bin(二元,即比較是基于字符編碼的值而與language無關(guān))結(jié)束
?
6.MySQL字符集的設(shè)置
- MySQL的字符集和校對(duì)規(guī)則有4個(gè)級(jí)別的默認(rèn)設(shè)置:服務(wù)器級(jí)、數(shù)據(jù)庫級(jí)、表級(jí)、字段級(jí)。他們分別在不同的地方設(shè)置,作用也不相同
- 服務(wù)器字符集和校對(duì)規(guī)則
服務(wù)器字符集和校對(duì)規(guī)則,可以在MySQL服務(wù)啟動(dòng)的確定。
可以在 my.cnf 中設(shè)置
character-set-server=gbk
或者在啟動(dòng)選項(xiàng)中指定
mysqld --character-set-server=gbk
或者在編譯時(shí)指定
cmake . -DEFAULT_CHARSET=gbk
如果沒有特別的指定服務(wù)器字符集,那么默認(rèn)使用latin1作為服務(wù)器字符集。上面3種設(shè)置的方式都只制定了字符集,沒有指定校對(duì)規(guī)則,這樣意味著使用該字符集默認(rèn)的校對(duì)規(guī)則。如果要使用該字符集非默認(rèn)的校對(duì)規(guī)則,則需要在指定字符集的同時(shí)指定校對(duì)規(guī)則。
查詢當(dāng)前服務(wù)器的字符集和校對(duì)規(guī)則
SHOW VARIABLES LIKE 'character_set_server' - 數(shù)據(jù)庫字符集和校對(duì)規(guī)則
數(shù)據(jù)庫的字符集和校對(duì)規(guī)則在創(chuàng)建數(shù)據(jù)庫的時(shí)候指定,也可以在創(chuàng)建完數(shù)據(jù)庫后通過ALTER DATABASE命令進(jìn)行修改。需要注意的是,如果數(shù)據(jù)庫里已經(jīng)存在數(shù)據(jù),因?yàn)樾薷淖址⒉荒軐⒁延械臄?shù)據(jù)按照新的字符集進(jìn)行存放,所以不能通過修改數(shù)據(jù)庫的字符集直接修改數(shù)據(jù)的內(nèi)容。
設(shè)置數(shù)據(jù)庫字符集的規(guī)則如下:
如果指定了字符集和校對(duì)規(guī)則。則使用指定的字符集和校對(duì)規(guī)則
如果指定了字符集沒有指定校對(duì)規(guī)則,則使用指定字符集的默認(rèn)校對(duì)規(guī)則
如果指定了校對(duì)規(guī)則但未指定字符集,則字符集使用與該校對(duì)規(guī)則關(guān)聯(lián)的字符集
如果沒有指定字符集和校對(duì)規(guī)則,則使用服務(wù)器字符集和校對(duì)規(guī)則作為數(shù)據(jù)庫的字符集和校對(duì)規(guī)則
推薦在創(chuàng)建數(shù)據(jù)庫時(shí)明確指定字符集和校對(duì)規(guī)則,避免受到默認(rèn)值的影響。
顯示當(dāng)前數(shù)據(jù)庫默認(rèn)的字符集和校對(duì)規(guī)則
SHOW VARIABLES LIKE 'character_set_database'
SHOW VARIABLES LIKE 'collation_database' - 表字符集和校對(duì)規(guī)則
表的字符集和校對(duì)規(guī)則在創(chuàng)建表的時(shí)候指定,可以通過ALTER TABLE 命令進(jìn)行修改,同樣,如果表中已有記錄,修改字符集對(duì)原有的記錄并沒有影響,不會(huì)按照新的字符集進(jìn)行存放。表的字段仍然使用原來的字符集。
設(shè)置表的字符集的規(guī)則
如果指定了字符集和校對(duì)規(guī)則。則使用指定的字符集和校對(duì)規(guī)則
如果指定了字符集沒有指定校對(duì)規(guī)則,則使用指定字符集的默認(rèn)校對(duì)規(guī)則
如果指定了校對(duì)規(guī)則但未指定字符集,則字符集使用與該校對(duì)規(guī)則關(guān)聯(lián)的字符集
如果沒有指定字符集和校對(duì)規(guī)則,則使用數(shù)據(jù)庫字符集和校對(duì)規(guī)則作為數(shù)據(jù)庫的字符集和校對(duì)規(guī)則
推薦在創(chuàng)建表的時(shí)候明確指定字符集和校對(duì)規(guī)則,以避免受到默認(rèn)值得影響。
顯示表的字符集和校對(duì)規(guī)則
SHOW CREATE TABLE table_name - 列字符集和校對(duì)規(guī)則
MySQL可以定義列級(jí)別的字符集和校對(duì)規(guī)則,主要是針對(duì)相同的表不同字符需要使用不同的字符集情況,應(yīng)該說一般遇到這種情況的幾率比較小,這只是MySQL提供給我們一個(gè)靈活設(shè)置的手段。
列字符集和校對(duì)規(guī)則的定義可以在創(chuàng)建表時(shí)指定,或者在修改表時(shí)調(diào)整,如果在創(chuàng)建表的時(shí)候沒有特別指定字符集和校對(duì)規(guī)則,則默認(rèn)使用表的字符集和校對(duì)規(guī)則。 - 連接字符集和校對(duì)規(guī)則
上面4種設(shè)置方式,確定的是數(shù)據(jù)保存的字符子和校對(duì)規(guī)則,對(duì)于實(shí)際應(yīng)用訪問來說,還存在客戶端和服務(wù)器之間交互的字符集和校對(duì)規(guī)則的設(shè)置。
對(duì)于客戶端和服務(wù)器的交互操作,MySQL提供了3個(gè)不同的參數(shù):
character_set_client 客戶端
character_set_connection 連接
character_set_results 返回結(jié)果的字符集
通常情況下,這3個(gè)字符集應(yīng)該是相同的,才可以確保用戶寫入的數(shù)據(jù)可以正確的讀出,特別是對(duì)于中文字符,不同的寫入字符集和返回結(jié)果字符集將導(dǎo)致寫入的記錄不能正確的讀出。
通常情況下,不會(huì)單個(gè)的設(shè)置這3個(gè)參數(shù),可以通過以下命令:
SET NAMES ***
來設(shè)置連接的字符集和校對(duì)規(guī)則,這個(gè)命令可以同時(shí)修改這3個(gè)參數(shù)的值。使用這個(gè)方法修改連接的字符集和校對(duì)規(guī)則,需要應(yīng)用每次連接數(shù)據(jù)庫后都執(zhí)行這個(gè)命令。
另一個(gè)更簡便的方法,是在my.cnf中設(shè)置以下語句:
t-character-set=gbk
這樣服務(wù)器啟動(dòng)后,所有連接默認(rèn)就是使用GBK字符集進(jìn)行連接的,而不需要在程序中在執(zhí)行set names命令。
另外,字符串常量的字符集也是由character_set_connection參數(shù)來指定的
可以通過 [_charset_name] 'string' [COLLATE collation_name] 命令強(qiáng)制字符串的字符集和校對(duì)規(guī)則。通常情況下,基本不需要用戶強(qiáng)制指定字符串字符集。
?
7.字符集的修改步驟
- 如果在應(yīng)用開始階段沒有正確的設(shè)置字符集,在運(yùn)行一段時(shí)間以后才發(fā)現(xiàn)存在不能滿足要求需要調(diào)整,又不想丟棄這段時(shí)間的數(shù)據(jù),那么就需要進(jìn)行字符集的修改。
字符集修改不能直接通過ALTER TABLE CHARACTER SET *** 或 ALTER TABLE table_name character set *** 命令進(jìn)行,這兩個(gè)命令都沒有更新已有記錄的字符集,而只是對(duì)創(chuàng)建的表或者記錄生效。已有記錄的字符集調(diào)整,需要先將數(shù)據(jù)導(dǎo)出,經(jīng)過適當(dāng)?shù)恼{(diào)整重新導(dǎo)入后才可完成。 - 選擇目標(biāo)字符集的時(shí)候,要注意最好是源字符集的超集,或者確定比源字符集的字庫更大,否則如果目標(biāo)字符集的字符小于源字符集的字庫,那么目標(biāo)字符集中不支持的字符導(dǎo)入后會(huì)變成亂碼,丟失一部分?jǐn)?shù)據(jù)。
實(shí)例:
模擬將latin1字符集的數(shù)據(jù)庫修改成GBK字符集的數(shù)據(jù)庫的過程
1) 導(dǎo)出表結(jié)構(gòu)
mysqldump -uroot -p --default-character-set=gbk -d databasename > createtab.sql
? ?其中--default-character-set=gbk表示設(shè)置以什么字符集連接,-d表示只導(dǎo)出表結(jié)構(gòu),不導(dǎo)出數(shù)據(jù)
2) 手工修改createtab.sql中表結(jié)構(gòu)定義中的字符集為新的字符集
3) 確保記錄不再更新,導(dǎo)出所有記錄
mysqldump -uroot -p --quick --no-create-info --extended-insert --default-character-set=latin1 databasename > data.sql
--quick:該選項(xiàng)用于轉(zhuǎn)出打的表。他強(qiáng)制mysqldump從服務(wù)器一次一行地檢索表中的行而不是檢索所有行,并在輸出前將他緩存到內(nèi)存中
--extended-insert:使用包括幾個(gè)VALUES列表的多行INSERT語法。這樣使轉(zhuǎn)出文件更小,重載文件時(shí)可以加速插入
--no-create-info:不導(dǎo)出每個(gè)轉(zhuǎn)儲(chǔ)表的CREATE TABLE語句
--default-character-set=latin1:按照原有的字符集導(dǎo)出所有數(shù)據(jù)就,這樣導(dǎo)出的文件中,所有中文都是可見的。不會(huì)保存成亂碼
4) 打開data.sql,將SET NAMES latin1修改成SET NAMES gbk
5) 使用新的字符集創(chuàng)建新的數(shù)據(jù)庫
CREATE DATABASE database_name
DEFAULT CHARSET charset_name
6) 創(chuàng)建表,執(zhí)行 createtab.sql
mysql -uroot -p databasename < createtab.sql
7) 導(dǎo)入數(shù)據(jù),執(zhí)行data.sql
mysql -uroot -p databasename < data.sql
轉(zhuǎn)載于:https://www.cnblogs.com/microcat/p/6606028.html
總結(jié)
以上是生活随笔為你收集整理的MySQL--字符集的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: FOR JENNIFER MORRISO
- 下一篇: StringUtil工具类: