深入Mysql字符集設定分析

2022-10-03 12:48:11 字數 3191 閱讀 4883

基本概念

• 字元(character)是指人類語言中最小的表義符號。例如'a'、'b'等;

• 給定一系列字元,對每個字元賦予乙個數值,用數值來代表對應的字元,這一數值就是字元的編碼(encoding)。例如,我們給字元'a'賦予數值0,給字元'b'賦予數值1,則0就是字元'a'的編碼;

• 給定一系列字元並賦予對應的編碼後,所有這些字元和編碼對組成的集合就是字符集(character set)。例如,給定字元列表為時,就是乙個字符集;

• 字元序(collation)是指在同一字符集內字元之間的比較規則;

• 確定字元序後,才能在乙個字符集上定義什麼是等價的字元,以及字元之間的大小關係;

̶程式設計客棧6; 每個字元序唯一對應一種字符集,但乙個字符集可以對應多種字元序,其中有乙個是預設字元序(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:當前選中資料庫的預設字符集

– charijnhhhacter_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%';

• s函式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字符集設定分析

本文位址:

深入Mysql字符集設定

字元 character 是指人類語言中最小的表義符號。例如 a b 等 給定一系列字元,對每個字元賦予乙個數值,用數值來代表對應的字元,這一數值就是字元的編碼 encoding 例如,我們給字元 a 賦予數值0,給字元 b 賦予數值1,則0就是字元 a 的編碼 給定一系列字元並賦予對應的編碼後,所...

深入Mysql字符集設定

基本概念 字元 character 是指人類語言中最小的表義符號。例如 a b 等 給定一系列字元,對每個字元賦予乙個數值,用數值來代表對應的字元,這一數值就是字元的編碼 encoding 例如,我們給字元 a 賦予數值0,給字元 b 賦予數值1,則0就是字元 a 的編碼 給定一系列字元並賦予對應的...

Mysql字符集設定分析

基本概念 字元 character 是指人類語言中最小的表義符號。例如 a b 等 給定一系列字元,對每個字元賦予乙個數值,用數值來代表對應的字元,這一數值就是字元的編碼 encoding 例如,我們給字元 a 賦予數值0,給字元 b 賦予數值1,則0就是字元 a 的編碼 給定一系列字元並賦予對應的...