mysql的字符集設置眾多,從客戶端到連接到結果集,從服務器到庫到表到列,都可以設置字符集,靈活很強大,但就是很容易出問題,如果不了解其機制,很容易就出現亂碼問題。
為了讓大家盡量在工作中少受或者不受亂碼的困擾,這里我結合之前其它同學在論壇的發帖,并結合自己的理解和實踐,詳細分析總結了一下,以饗各位看官。
關于字符集和亂碼的基礎知識這里就不詳細說明了(請自行搜索),但有一個問題需要特別強調一下:亂碼是怎么產生的?
這個問題相信很多同學都是模棱兩可,或者沒有認真想過,反正理解就是”字符編碼“不對導致亂碼,但沒有真正想過為什么”字符編碼“會導致亂碼。
答案其實很簡單:“轉換導致亂碼”!
根據這個原則來判斷,各種情況就很簡單了:
1)數據傳送過程中不會導致亂碼
2)數據存儲不會導致亂碼
3)數據輸入和輸出(包括顯示)可能導致亂碼
4)數據接收和發送可能導致亂碼
更詳細的解釋:轉換導致亂碼是指本來是A字符集的數據被當成了B字符集進行解析,而不是說正確的A字符集轉換為B字符集。
例如:如下mysql字符處理機制流程圖中,mysql客戶端發送的實際上是2個gbk字符(4字節),但character_set_connection
設置了utf8,于是mysql服務器將收到的4字節gbk數據按照utf8解析,得到1個中文字符+1個字節,這時就產生亂碼了;
如果character_set_connection 設置為gbk,mysql服務器收到數據后按照gbk解析,得到兩個正確的中文,然后再轉換為這兩個中文對應的utf8編碼,這就不會產生亂碼。)
【mysql的字符處理機制】
詳細的處理機制如下圖:

我們模擬一下一條數據從插入到讀取的處理流程,看看在整個流程中,字符集是如何輾轉騰挪的。
【插入流程】
1. 客戶端設定了自己的編碼(character_set_client),接收用戶的輸入;
2. 客戶端將用戶的輸入“轉換”成連接的編碼(character_set_connection) =====> 第一次轉換
3. 客戶端將轉換后的數據發送給服務器; =====> 傳輸不會導致編碼轉換
4. 服務器收到客戶端的數據,再判斷數據列的字符集,進行字符轉換 =====> 第二次轉換
5. 服務器將數據存儲(例如磁盤) =====> 存儲不會導致編碼轉換
新聞熱點
疑難解答