基本概念
• 字元(character)是指人類語言中最小的表義符號。例如』a'、』b'等;
• 給定一系列字元,對每個字元賦予乙個數值,用數值來代表對應的字元,這一數值就是字元的編碼(encoding)。例如,我們給字元』a'賦予數值0,給字元』b'賦予數值1,則0就是字元』a'的編碼;
• 給定一系列字元並賦予對應的編碼後,所有這些字元和編碼對組成的集合就是字符集(character set)。例如,給定字元列表為時,就是乙個字符集;
• 字元序(collation)是指在同一字符集內字元之間的比較規則;
• 確定字元序後,才能在乙個字符集上定義什麼是等價的字元,以及字元之間的大小關係;
• 每個字元序唯一對應一種字符集,但乙個字符集可以對應多種字元序,其中有乙個是預設字元序(default collation);
• mysql中的字元序名稱遵從命名慣例:以字元序對應的字符集名稱開頭;以_ci(表示大小寫不敏感)、_cs(表示大小寫敏感)或_bin(表示按編碼值比較)結尾。例如:在字元序「utf8_general_ci」下,字元「a」和「a」是等價的;
mysql字符集設定
• 系統變數:
–character_set_server:預設的內部操作字符集
–character_set_client:客戶端**資料使用的字符集
–character_set_connection:連線層字符集
–character_set_results:查詢結果字符集
–character_set_database:當前選中資料庫的預設字符集
–character_set_system:系統元資料(欄位名等)字符集
– 還有以collation_開頭的同上面對應的變數,用來描述字元序。
• 用introducer指定文字字串的字符集:
– 格式為:[_charset] 『string』 [collate collation]
– 例如:
• select _latin1 『string』;
• select _utf8 『你好』 collate utf8_general_ci;
– 由introducer修飾的文字字串在請求過程中不經過多餘的轉碼,直接轉換為內部字符集處理。
mysql中的字符集轉換過程
1. mysql server收到請求時將請求資料從character_set_client轉換為character_set_connection;
2. 進行內部操作前將請求資料從character_set_connection轉換為內部操作字符集,其確定方法如下:
• 使用每個資料字段的character set設定值;
• 若上述值不存在,則使用對應資料表的default character set設定值(mysql擴充套件,非sql標準);
• 若上述值不存在,則使用對應資料庫的default character set設定值;
• 若上述值不存在,則使用character_set_server設定值。
3. 將操作結果從內部操作字符集轉換為character_set_results。
常見問題解析
• 向預設字符集為utf8的資料表插入utf8編碼的資料前沒有設定連線字符集,查詢時設定連線字符集為utf8
– 插入時根據mysql伺服器的預設設定,character_set_client、character_set_connection和character_set_results均為latin1;
– 插入操作的資料將經過latin1=>latin1=>utf8的字符集轉換過程,這一過程中每個插入的漢字都會從原始的3個位元組變成6個位元組儲存;
– 查詢時的結果將經過utf8=>utf8的字符集轉換過程,將儲存的6個位元組原封不動返回,產生亂碼……
• 向預設字符集為latin1的資料表插入utf8編碼的資料前設定了連線字符集為utf8
– 插入時根據連線字符集設定,character_set_client、character_set_connection和character_set_results均為utf8;
– 插入資料將經過utf8=>utf8=>latin1的字符集轉換,若原始資料中含有\u0000~\u00ff範圍以外的unicode字 符,會因為無法在latin1字符集中表示而被轉換為「?」(0x3f)符號,以後查詢時不管連線字符集設定如何都無法恢復其內容了。
檢測字符集問題的一些手段
• show character set;
• show collation;
• show variables like 『character%』;
• show variables like 『collation%』;
• sql函式hex、length、char_length
• sql函式charset、collation
使用mysql字符集時的建議
• 建立資料庫/表和進行資料庫操作時盡量顯式指出使用的字符集,而不是依賴於mysql的預設設定,否則mysql公升級時可能帶來很大困擾;
• 資料庫和連線字符集都使用latin1時雖然大部分情況下都可以解決亂碼問題,但缺點是無法以字元為單位來進行sql操作,一般情況下將資料庫和連線字符集都置為utf8是較好的選擇;
• 使用mysql c api時,初始化資料庫控制代碼後馬上用mysql_options設定mysql_set_charset_name屬性為utf8,這樣就不用顯式地用 set names語句指定連線字符集,且用mysql_ping重連斷開的長連線時也會把連線字符集重置為utf8;
• 對於mysql php api,一般頁面級的php程式總執行時間較短,在連線到資料庫以後顯式用set names語句設定一次連線字符集即可;但當使用長連線時,請注意保持連線通暢並在斷開重連後用set names語句顯式重置連線字符集。
其他注意事項
• my.cnf中的default_character_set設定只影響mysql命令連線伺服器時的連線字符集,不會對使用libmysqlclient庫的應用程式產生任何作用!
• 對欄位進行的sql函式操作通常都是以內部操作字符集進行的,不受連線字符集設定的影響。
• sql語句中的裸字串會受到連線字符集或introducer設定的影響,對於比較之類的操作可能產生完全不同的結果,需要小心!
深入Mysql字符集設定
字元 character 是指人類語言中最小的表義符號。例如 a b 等 給定一系列字元,對每個字元賦予乙個數值,用數值來代表對應的字元,這一數值就是字元的編碼 encoding 例如,我們給字元 a 賦予數值0,給字元 b 賦予數值1,則0就是字元 a 的編碼 給定一系列字元並賦予對應的編碼後,所...
深入Mysql字符集設定分析
基本概念 字元 character 是指人類語言中最小的表義符號。例如 a b 等 給定一系列字元,對每個字元賦予乙個數值,用數值來代表對應的字元,這一數值就是字元的編碼 encoding 例如,我們給字元 a 賦予數值0,給字元 b 賦予數值1,則0就是字元 a 的編碼 給定一系列字元並賦予對應的...
mysql字符集設定
show variables like char show variables like collation 2.修改編碼 set variable name value set character set connection utf8 3 顯示建立資料庫資訊 show create databa...