MySQL相關(二)——— 字符編碼

在閱讀代碼的時候,經??吹接龅竭@樣一句

$this->pdo->exec("SET NAMES '" . $config["charset"] . "'");

心生疑惑 ,“為什么在數據讀寫之前,要寫這樣一句”。

求助了一下搜索引擎,原來是為了避免亂碼的出現。下面就來說說 MySQL 為什么會出現亂碼以及解決亂碼的方法

先明確幾個概念

什么是字符集(character set)呢mysql 的文檔給了一個很容易理解的例子

假設有個包含4個字符的字母表 A,B,a,b。
給每個字母編一個號,A=0,B=1,a=2,b=3
這里的 A 就是 符號(symbol),0 就是 A 的編碼(encoding)
符號和符號對應的編碼就組成了一個字符集

那么什么又是 collation 呢?

簡單來說,它就是 order by 時,用來排序的規則。

字符集 utf8 下常用的 collation 有 utf8_general_ci、utf8__bin。

ci 指的就是case incensitive,大小寫不敏感。比較時,a 和 A 是相同的

為什么會出現亂碼?

MySQL 的中的字符集變量

  • character_set_server:默認的內部操作字符集
  • character_set_client:客戶端來源數據使用的字符集
  • character_set_connection:連接層字符集
  • character_set_results:查詢結果字符集
  • character_set_database:當前選中數據庫的默認字符集
  • character_set_system:系統元數據(字段名等)字符集
  • 還有以collation_開頭的同上面對應的變量,用來描述字符序

客戶端要讀寫數據庫時,需要建立一條數據庫連接 connection。

數據從客戶端到服務端

數據在 connection 上,傳輸的過程中需要經過編碼轉換

character_set_client ---> character_set_connection ---> column_character_set
                                                   |--> table_character_set
                                                   |--> database_character_set
                                                   |--> character_set_server
                                                   |--> character_set_result
                                                
  • 服務端收到客戶端的數據時,認為客戶端的數據編碼為 character_ser_client
  • 隨后將從客戶端接收到的數據,轉換為 character_set_connection編碼
  • 在需要進行數據庫內部操作(寫到表等)的時候,將 character_set_connection 編碼轉換字段、表、數據庫、服務器對應的編碼類型
  • 若以上值不存在,則轉化為 character_set_results

數據從服務端到客戶端

character_set_result ---> character_set_connection ---> character_set_client

為數據從客戶端到服務端相反過程

可以看到轉換過程中,有幾個地方可能會產生亂碼

  • character_set_client 和真實的客戶端編碼不同
  • client->server, server->client 兩個過程中使用的編碼不一致
  • 編碼轉換不可逆,導致信息丟失

這里有解決辦法

在進行連接后,就進行設置編碼,之后的讀寫都不再改變

SET NAMES character_name 相當于

SET character_set_client = charset_name;
SET character_set_results = charset_name;
SET character_set_connection = charset_name;

這樣可以解決上述的前連個問題

但是第三個問題,要看數轉換的數據是否存在兩個字符集之間的轉換不可逆的字符

如有錯誤,還望指正!

參考

[1] 深入Mysql字符集設置

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容