《Mysql必讀mysql字符集設(shè)置經(jīng)驗(yàn)技巧》要點(diǎn):
本文介紹了Mysql必讀mysql字符集設(shè)置經(jīng)驗(yàn)技巧,希望對(duì)您有用。如果有疑問(wèn),可以聯(lián)系我們。
本節(jié)內(nèi)容:
mysql字符集設(shè)置方法總結(jié)MYSQL入門(mén)
一,基本概念MYSQL入門(mén)
字符(character)是指人類語(yǔ)言中最小的表義符號(hào).例如’a'、’b'等;
給定一系列字符,對(duì)每個(gè)字符賦予一個(gè)數(shù)值,用數(shù)值來(lái)代表對(duì)應(yīng)的字符,這一數(shù)值就是字符的編碼(encoding).MYSQL入門(mén)
例如,給字符’a'賦予數(shù)值0,給字符’b'賦予數(shù)值1,則0就是字符’a'的編碼;
給定一系列字符并賦予對(duì)應(yīng)的編碼后,所有這些字符和編碼對(duì)組成的集合就是字符集(character set).MYSQL入門(mén)
例如,給定字符列表為{’a',’b'}時(shí),{’a'=>0, ‘b’=>1}就是一個(gè)字符集;
字符序(collation)是指在同一字符集內(nèi)字符之間的比較規(guī)則;
確定字符序后,才能在一個(gè)字符集上定義什么是等價(jià)的字符,以及字符之間的大小關(guān)系;
每個(gè)字符序唯一對(duì)應(yīng)一種字符集,但一個(gè)字符集可以對(duì)應(yīng)多種字符序,其中有一個(gè)是默認(rèn)字符序(default collation);
mysql中的字符序名稱遵從命名慣例:以字符序?qū)?yīng)的字符集名稱開(kāi)頭;以_ci(表示大小寫(xiě)不敏感)、_cs(表示大小寫(xiě)敏感)或_bin(表示按編碼值比較)結(jié)尾.例如:在字符序“utf8_general_ci”下,字符“a”和“a”是等價(jià)的;MYSQL入門(mén)
二,mysql字符集設(shè)置MYSQL入門(mén)
系統(tǒng)變量:
?MYSQL入門(mén)
用introducer指定文本字符串的字符集:
?MYSQL入門(mén)
三,mysql中的字符集轉(zhuǎn)換過(guò)程MYSQL入門(mén)
1. mysql server收到請(qǐng)求時(shí)將請(qǐng)求數(shù)據(jù)從character_set_client轉(zhuǎn)換為character_set_connection;
2. 進(jìn)行內(nèi)部操作前將請(qǐng)求數(shù)據(jù)從character_set_connection轉(zhuǎn)換為內(nèi)部操作字符集,其確定方法如下:
? - 使用每個(gè)數(shù)據(jù)字段的character set設(shè)定值;
? - 若上述值不存在,則使用對(duì)應(yīng)數(shù)據(jù)表的default character set設(shè)定值(mysql擴(kuò)展,非sql標(biāo)準(zhǔn));
? - 若上述值不存在,則使用對(duì)應(yīng)數(shù)據(jù)庫(kù)的default character set設(shè)定值;
? - 若上述值不存在,則使用character_set_server設(shè)定值.MYSQL入門(mén)
3. 將操作結(jié)果從內(nèi)部操作字符集轉(zhuǎn)換為character_set_results.
現(xiàn)在回過(guò)頭來(lái)分析下我們產(chǎn)生的亂碼問(wèn)題:
a 字段沒(méi)有設(shè)置字符集,因此使用表的數(shù)據(jù)集
b 表沒(méi)有指定字符集,默認(rèn)使用數(shù)據(jù)庫(kù)存的字符集
c 數(shù)據(jù)庫(kù)在創(chuàng)建時(shí)沒(méi)有指定字符集,因此使用character_set_server設(shè)定值
d 沒(méi)有特意去修改character_set_server的指定字符集,因此使用mysql默認(rèn)
e mysql默認(rèn)的字符集是latin1,因此,使用了latin1字符集,而我們character_set_connection的字符集是utf-8,插入中文亂碼也再所難免了.MYSQL入門(mén)
四,常見(jiàn)問(wèn)題解析
faq-1 向默認(rèn)字符集為utf8的數(shù)據(jù)表插入utf8編碼的數(shù)據(jù)前沒(méi)有設(shè)置連接字符集,查詢時(shí)設(shè)置連接字符集為utf8
???? – 插入時(shí)根據(jù)mysql服務(wù)器的默認(rèn)設(shè)置,character_set_client、character_set_connection和character_set_results均為latin1;
???? – 插入操作的數(shù)據(jù)將經(jīng)過(guò)latin1=>latin1=>utf8的字符集轉(zhuǎn)換過(guò)程,這一過(guò)程中每個(gè)插入的漢字都會(huì)從原始的3個(gè)字節(jié)變成6個(gè)字節(jié)保存;
???? – 查詢時(shí)的結(jié)果將經(jīng)過(guò)utf8=>utf8的字符集轉(zhuǎn)換過(guò)程,將保存的6個(gè)字節(jié)原封不動(dòng)返回,產(chǎn)生亂碼.參考下圖:
向默認(rèn)字符集為latin1的數(shù)據(jù)表插入utf8編碼的數(shù)據(jù)前設(shè)置了連接字符集為utf8(我們遇到的錯(cuò)誤就是屬于這一種)
???? – 插入時(shí)根據(jù)連接字符集設(shè)置,character_set_client、character_set_connection和character_set_results均為utf8;
???? --插入數(shù)據(jù)將經(jīng)過(guò)utf8=>utf8=>latin1的字符集轉(zhuǎn)換,若原始數(shù)據(jù)中含有u0000~u00ff范圍以外的unicode字符,會(huì)因?yàn)闊o(wú)法在latin1字符集中表示而被轉(zhuǎn)換為“?”(0×3f)符號(hào),以后查詢時(shí)不管連接字符集設(shè)置如何都無(wú)法恢復(fù)其內(nèi)容了.轉(zhuǎn)換過(guò)程如下圖:?MYSQL入門(mén)
五,檢測(cè)字符集問(wèn)題的一些手段
?MYSQL入門(mén)
六,使用mysql字符集時(shí)的建議
??? 建立數(shù)據(jù)庫(kù)/表和進(jìn)行數(shù)據(jù)庫(kù)操作時(shí)盡量顯式指出使用的字符集,而不是依賴于mysql的默認(rèn)設(shè)置,否則mysql升級(jí)時(shí)可能帶來(lái)很大困擾;
??? 數(shù)據(jù)庫(kù)和連接字符集都使用latin1時(shí),雖然大部分情況下都可以解決亂碼問(wèn)題,但缺點(diǎn)是無(wú)法以字符為單位來(lái)進(jìn)行sql操作,一般情況下將數(shù)據(jù)庫(kù)和連接字符集都置為utf8是較好的選擇;
??? 使用mysql capi(mysql提供c語(yǔ)言操作的api)時(shí),初始化數(shù)據(jù)庫(kù)句柄后馬上用mysql_options設(shè)定mysql_set_charset_name屬性為utf8,這樣就不用顯式地用set names語(yǔ)句指定連接字符集,且用mysql_ping重連斷開(kāi)的長(zhǎng)連接時(shí)也會(huì)把連接字符集重置為utf8;
??? 對(duì)于mysql php api,一般頁(yè)面級(jí)的php程序總運(yùn)行時(shí)間較短,在連接到數(shù)據(jù)庫(kù)以后顯式用set names語(yǔ)句設(shè)置一次連接字符集即可;但當(dāng)使用長(zhǎng)連接時(shí),請(qǐng)注意保持連接通暢并在斷開(kāi)重連后用set names語(yǔ)句顯式重置連接字符集.
?
七,其他注意事項(xiàng)
??? my.cnf中的default_character_set設(shè)置只影響mysql命令連接服務(wù)器時(shí)的連接字符集,不會(huì)對(duì)使用libmysqlclient庫(kù)的應(yīng)用程序產(chǎn)生任何作用!
??? 對(duì)字段進(jìn)行的sql函數(shù)操作通常都是以內(nèi)部操作字符集進(jìn)行的,不受連接字符集設(shè)置的影響.
??? sql語(yǔ)句中的裸字符串會(huì)受到連接字符集或introducer設(shè)置的影響,對(duì)于比較之類的操作可能產(chǎn)生完全不同的結(jié)果,需要小心!
?
在創(chuàng)建database時(shí)指定字符集,不要去通過(guò)修改默認(rèn)配置來(lái)達(dá)到目的,當(dāng)然也可以采用指定表的字符集的形式,但很容易出現(xiàn)遺漏,特別是在很多人都參與設(shè)計(jì)時(shí),更容易紕漏.
?
雖然不提倡通過(guò)修改mysql的默認(rèn)字符集來(lái)解決,但對(duì)于如何去修改默認(rèn)字符集,不過(guò)還是給出一些方法,僅供大家參考.
?
### mysql默認(rèn)字符集MYSQL入門(mén)
mysql對(duì)于字符集的指定可以細(xì)化到一個(gè)數(shù)據(jù)庫(kù),一張表,一列.傳統(tǒng)的程序在創(chuàng)建數(shù)據(jù)庫(kù)和數(shù)據(jù)表時(shí)并沒(méi)有使用那么復(fù)雜的配置,它們用的是默認(rèn)的配置.
??? (1)編譯mysql 時(shí),指定了一個(gè)默認(rèn)的字符集,這個(gè)字符集是 latin1;
??? (2)安裝mysql 時(shí),可以在配置文件 (my.ini) 中指定一個(gè)默認(rèn)的的字符集,如果沒(méi)指定,這個(gè)值繼承自編譯時(shí)指定的;
??? (3)啟動(dòng)mysqld 時(shí),可以在命令行參數(shù)中指定一個(gè)默認(rèn)的的字符集,如果沒(méi)指定,這個(gè)值繼承自配置文件中的配置,此時(shí) character_set_server 被設(shè)定為這個(gè)默認(rèn)的字符集;
??? (4)安裝 mysql選擇多語(yǔ)言支持,安裝程序會(huì)自動(dòng)在配置文件中把default_character_set 設(shè)置為 utf-8,保證缺省情況下所有的數(shù)據(jù)庫(kù)所有表的所有列的都用 utf-8 存儲(chǔ).MYSQL入門(mén)
1,查看默認(rèn)字符集
?(默認(rèn)情況下,mysql的字符集是latin1(iso_8859_1),以上已給出了相關(guān)命令.MYSQL入門(mén)
2,修改mysql默認(rèn)字符集MYSQL入門(mén)
1)、最簡(jiǎn)單的修改方法,修改mysql的my.ini文件中的字符集鍵值,
例如:
?MYSQL入門(mén)
修改完后,重啟mysql的服務(wù)
2)、另一種修改字符集的方法,使用mysql的命令
????MYSQL入門(mén)
問(wèn)題:設(shè)置了表的默認(rèn)字符集為utf8并且通過(guò)utf-8編碼發(fā)送查詢,存入數(shù)據(jù)庫(kù)的仍然是亂碼.
那connection連接層上可能出了問(wèn)題.MYSQL入門(mén)
解決方法:
在發(fā)送查詢前執(zhí)行語(yǔ)句: set names 'utf8';MYSQL入門(mén)
它相當(dāng)于下面的三句指令:
?MYSQL入門(mén)
《Mysql必讀mysql字符集設(shè)置經(jīng)驗(yàn)技巧》是否對(duì)您有啟發(fā),歡迎查看更多與《Mysql必讀mysql字符集設(shè)置經(jīng)驗(yàn)技巧》相關(guān)教程,學(xué)精學(xué)透。維易PHP學(xué)院為您提供精彩教程。
轉(zhuǎn)載請(qǐng)注明本頁(yè)網(wǎng)址:
http://www.snjht.com/jiaocheng/7416.html