《Mysql是怎樣執行的》讀書筆記三
字符集和比較規則
將字元對映成二進位制的過程叫做編碼,將二進位制對映成字元的過程叫做解碼。
我們看一下常用字符集的情況:
ASCII字符集:
共收錄128個字元,包括空格、標點符號、數字、大小寫字母和一些不可見字元。
ISO 8859-1字符集:
共收錄256個字元,它在ASCII字符集
的基礎上有擴充了128個西歐常用字元。
GB2312字符集:
收錄了漢字以及拉丁字母、希臘字母、日文平假名以及片假名字母、俄語西裡爾字母,收錄漢字6763個。
GBK字符集
:GBK字符集
在GB2312字符集進行了擴充。
UTF-8字符集:
幾乎收錄了當今世界各個國家/地區使用的字元,而且還在不斷擴充。
umf8mb3:"閹割"過的UTF-8字符集,使用1~3位元組表示字元。 umf8mb4:正宗的UTF-8字符集,使用1~4位元組表示字元。
utf8是使用umf8mb3的別名。
比較規則是對某個字符集中字元比較大小的一種規則,一種字符集對應若干種比較規則,其中有一個預設比較規則,一個比較規則必須對應一個字符集。
MySQL
有4個字符集和比較規則,分別是伺服器級別、資料庫級別、表級別、列級別。
伺服器級別
(1)檢視伺服器級別的字符集
mysql> show variables like 'character_set_server';
(2)檢視伺服器級別的比較規則
mysql> show variables like 'collation_server';
資料庫級別
(1)檢視資料庫級別的字符集
mysql> show variables like 'character_set_database';
(2)檢視資料庫級別的比較規則
mysql> show variables like 'collation_database';
表級別
我們可以在建立表和修改表的時候指定表的字符集和比較規則。如果表中沒有指定,則使用表所在的資料庫和字符集的比較規則作為該表的字符集和比較規則。
列級別
我們可以在建立列和修改列的時候指定列的字符集和比較規則。如果在建立列的沒有顯式指定字符集和比較規則,則該列預設使用表的字符集和比較規則。
客戶端與伺服器通訊過程的使用的字符集
從本質上說,伺服器接收到的請求就是一個位元組序列,伺服器將這個位元組序列看作是使用系統變數character_set_client
character_set_client
變數,是SESSION級別的)伺服器會將請求的位元組序列當做採用
character_set_client
對應的字符集進行編碼的位元組序列,在真正處理請求時轉換為使用SESSION級別的系統變數character_set_connection
對應的字符集進行編碼的位元組序列。在客戶端接收的值與表中的某列值比較時,列的字符集和排序規則的優先順序更高。例如,
select * from t where c='我';
“我”採用的gbk
編碼,列c
採用的utf8
字符集編碼,這裡需要將請求中的“我”先從gbk
字符集轉換為utf8
。
以上面為例,在伺服器生成響應的時候,伺服器會將字串“我”從utf8字符集編碼轉換character_set_result
系統變數對應的字符集編碼後的位元組序列,之後再發送給客戶端。
系統變數 | 描述 |
---|---|
character_set_client | 伺服器認為請求是按照該系統變數指定的字符集進行編碼 |
character_set_connection | 伺服器在處理請求時,會把請求位元組序列從 character_set_client轉換為character_set_connection |
character_set_result | 伺服器採用該系統變數指定的字符集對返回客戶端的字串進行編碼 |
在連線到伺服器時,客戶端將預設的字符集與使用者名稱、密碼等資訊一起傳送給伺服器,伺服器在接收後將character_set_client、character_set_connection
和character_set_result
這三個系統變數的值初始化為客戶端的預設字符集。