在mysql中什么情况下不能指定字符集_如何为Mysql选择合适的字符集?
MySQL服務器可以支持多種字符集,在同一臺服務器,同一個數據庫,甚至同一個表的不同字段都可以指定使用不同的字符集,相比Oracle等其他數據庫管理系統,在同一個數據庫只能使用相同的字符集,MySQL明顯存在更大的靈活性。
字符集概述
字符集是一套符號和編碼的規則,不論是在oracle數據庫還是在mysql數據庫,都存在字符集的選擇問題,而且如果在數據庫創建階段沒有正確選擇字符集,那么可能在后期需要更換字符集,而字符集的更換是代價比較高的操作,也存在一定的風險,所以,我們推薦在應用開始階段,就按照需求正確的選擇合適的字符集,避免后期不必要的調整。
?字符(Character)是指人類語言中最小的表義符號。例如’A'、’B'等;
?給定一系列字符,對每個字符賦予一個數值,用數值來代表對應的字符,這一數值就是字符的編碼(Encoding)。例如,我們給字符’A'賦予數值0,給字符’B'賦予數值1,則0就是字符’A'的編碼;
?給定一系列字符并賦予對應的編碼后,所有這些字符和編碼對組成的集合就是字符集(CharacterSet)。例如,給定字符列表為{’A',’B'}時,{’A'=>0,‘B’=>1}就是一個字符集;
?字符序(Collation)是指在同一字符集內字符之間的比較規則;
?確定字符序后,才能在一個字符集上定義什么是等價的字符,以及字符之間的大小關系;
?每個字符序唯一對應一種字符集,但一個字符集可以對應多種字符序,其中有一個是默認字符序(DefaultCollation);
?MySQL中的字符序名稱遵從命名慣例:以字符序對應的字符集名稱開頭;以_ci(表示大小寫不敏感)、_cs(表示大小寫敏感)或_bin(表示按編碼值比較)結尾。例如:在字符序“utf8_general_ci”下,字符“a”和“A”是等價的;
Mysql支持的字符集簡介
mysql服務器可以支持多種字符集(可以用showcharacterset命令查看所有mysql支持的字符集),在同一臺服務器、同一個數據庫、甚至同一個表的不同字段都可以指定使用不同的字符集,相比oracle等其他數據庫管理系統,在同一個數據庫只能使用相同的字符集,mysql明顯存在更大的靈活性。
mysql的字符集包括字符集(CHARACTER)和校對規則(COLLATION)兩個概念。字符集是用來定義mysql存儲字符串的方式,校對規則則是定義了比較字符串的方式。字符集和校對規則是一對多的關系,MySQL支持30多種字符集的70多種校對規則。
每個字符集至少對應一個校對規則。可以用SHOWCOLLATIONLIKE'utf8%';命令查看相關字符集的校對規則。
Unicode簡述
Unicode是一種編碼規范。我們在這里簡述一下Unicode編碼產生的歷史。
先從ASCII碼說起,ASCII碼也是一種編碼規范,只不過ASCII碼只能最多表示256個字符,是針對英文產生的,而面對中文、阿拉伯文之類的復雜文字,256個字符顯然是不夠用的。于是各個國家或組織都相繼制定了符合自己語言文字的標準,比如gb2312、big5等等。但是這種各自制定自己的標準的做法顯然是有很多弊端的,于是Unicode編碼規范應運而生。
Unicode也是一種字符編碼方法,不過它是由國際組織設計,可以容納全世界所有語言文字的編碼方案。Unicode的學名是"UniversalMultiple-OctetCodedCharacterSet",簡稱為UCS。UCS可以看作是"UnicodeCharacterSet"的縮寫。
Unicode有兩套標準UCS-2和UCS-4,前者用2個字節表示一個字符,后者用4個字節表示一個字符。以目前常用的UCS-2為例,它可以表示的字符數為2^16=65535,基本上可以容納所有的歐美字符和絕大多數亞洲字符。
怎樣選擇合適的字符集
我們建議在能夠完全滿足應用的前提下,盡量使用小的字符集。因為更小的字符集意味著能夠節省空間、減少網絡傳輸字節數,同時由于存儲空間的較小間接的提高了系統的性能。
有很多字符集可以保存漢字,比如utf8、gb2312、gbk、latin1等等,但是常用的是gb2312和gbk。因為gb2312字庫比gbk字庫小,有些偏僻字(例如:洺)不能保存,因此在選擇字符集的時候一定要權衡這些偏僻字在應用出現的幾率以及造成的影響,不能做出肯定答復的話最好選用gbk。
Mysql字符集的設置
mysql的字符集和校對規則有4個級別的默認設置:服務器級、數據庫級、表級和字段級。分別在不同的地方設置,作用也不相同。
服務器字符集和校對,在mysql服務啟動的時候確定。可以在my.cnf中設置:
[mysqld]
default-character-set=utf8
或者在啟動選項中指定:
mysqld--default-character-set=utf8
或者在編譯的時候指定:
./configure--with-charset=utf8
如果沒有特別的指定服務器字符集,默認使用latin1作為服務器字符集。上面三種設置的方式都只指定了字符集,沒有指定校對規則,這樣是使用該字符集默認的校對規則,如果要使用該字符集的非默認校對規則,則需要在指定字符集的同時指定校對規則。
可以用showvariableslike'character_set_server';命令查詢當前服務器的字符集和校對規則。
MySQL中的字符集轉換過程
1.MySQLServer收到請求時將請求數據從character_set_client轉換為character_set_connection;
2.進行內部操作前將請求數據從character_set_connection轉換為內部操作字符集,其確定方法如下:
-使用每個數據字段的CHARACTERSET設定值;
-若上述值不存在,則使用對應數據表的DEFAULTCHARACTERSET設定值(MySQL擴展,非SQL標準);
-若上述值不存在,則使用對應數據庫的DEFAULTCHARACTERSET設定值;
-若上述值不存在,則使用character_set_server設定值。
3.將操作結果從內部操作字符集轉換為character_set_results。
使用MySQL字符集時的建議
?建立數據庫/表和進行數據庫操作時盡量顯式指出使用的字符集,而不是依賴于MySQL的默認設置,否則MySQL升級時可能帶來很大困擾;
?數據庫和連接字符集都使用latin1時,雖然大部分情況下都可以解決亂碼問題,但缺點是無法以字符為單位來進行SQL操作,一般情況下將數據庫和連接字符集都置為utf8是較好的選擇;
?使用mysqlCAPI(mysql提供C語言操作的API)時,初始化數據庫句柄后馬上用mysql_options設定MYSQL_SET_CHARSET_NAME屬性為utf8,這樣就不用顯式地用SETNAMES語句指定連接字符集,且用mysql_ping重連斷開的長連接時也會把連接字符集重置為utf8;
?對于mysqlPHPAPI,一般頁面級的php程序總運行時間較短,在連接到數據庫以后顯式用SETNAMES語句設置一次連接字符集即可;但當使用長連接時,請注意保持連接通暢并在斷開重連后用SETNAMES語句顯式重置連接字符集。
其他注意事項
?my.cnf中的default_character_set設置只影響mysql命令連接服務器時的連接字符集,不會對使用libmysqlclient庫的應用程序產生任何作用!
?對字段進行的SQL函數操作通常都是以內部操作字符集進行的,不受連接字符集設置的影響。
?SQL語句中的裸字符串會受到連接字符集或introducer設置的影響,對于比較之類的操作可能產生完全不同的結果,需要小心!
小編結語:
根據上面的分析和建議,我們解決我們遇到問題應該使用什么方法大家心里應該比較清楚了。對,就是在創建database的時候指定字符集,不要去通過修改默認配置來達到目的,當然你也可以采用指定表的字符集的形式,但很容易出現遺漏,特別是在很多人都參與設計的時候,更容易紕漏。
與50位技術專家面對面20年技術見證,附贈技術全景圖總結
以上是生活随笔為你收集整理的在mysql中什么情况下不能指定字符集_如何为Mysql选择合适的字符集?的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 内存很空却频繁gc_NonRegiste
- 下一篇: 试题导入mysql乱码_解决Mysql导