字符集&字元編碼方式
字符集(character set)是多個字元的集合,字符集種類較多,每個字符集包含的字元個數不同,這裡的字元可以是英文本元,漢字字元,或者其他國家語言字元。
常見字符集包括:ascii字符集、latin1字符集、gb2312字符集、gbk字符集、gb18030字符集、unicode字符集等。字元編碼方式是用乙個或多個位元組表示字符集中的乙個字元。每種字符集都有自己特有的編碼方式,因此同乙個字元,在不同字符集的編碼方式下,會產生不同的二進位制。
ascii是基於羅馬字母表的一套字符集,它採用1個位元組的低7位表示字元,高位始終為0。latin1字符集相對於ascii字符集做了擴充套件,仍然使用乙個位元組表示字元,但啟用了高位,擴充套件了字符集的表示範圍。gb2312、gbk、gb18030字符集是支援中文的字符集,字符集範圍gb2312
mysql與字符集
只要涉及到文字的地方,就會存在字符集和編碼方式。對於mysql資料庫系統而言,使用者從mysql client端敲入一條sql語句,通過tcp/ip傳遞給mysql server程序,到最終存入server端的檔案,每個環節都涉及到字元儲存。涉及到字元儲存的地方,就涉及到字符集編碼,通過mysql提供的系統變數就可見一斑。mysql字符集設定系統變數以及含義如下表:
變數名 含義
character_set_server
預設的內部操作字符集
character_set_client
客戶端**資料使用的字符集
character_set_connection
連線層字符集
character_set_results
查詢結果字符集
character_set_database
當前選中資料庫的預設字符集
character_set_system
系統元資料(欄位名等)字符集
mysql字元編碼轉換流程
如果以上各個系統變數的設定不一致,比如character_set_client為utf8,而character_set_database為gbk,則會出現需要進行編碼轉換的情況。那麼字符集轉換的原理是什麼?假設gbk字符集的字串「小明」,需要轉為utf8字符集儲存,實際就是對於「小明」字串中的每個漢字去utf8編碼表裡面查詢對應的二進位制,然後儲存,僅此而已,編碼轉換並不涉及到複雜的演算法。mysql字符集轉換主要涉及到幾個步驟:
1) 將資料從character_set_client設定轉換為character_set_connection設定;
2) 將character_set_connection設定轉為表字段的字符集設定;
3) 將操作結果從表字段字符集轉為character_set_results設定。
下面我通過乙個常用的場景來描述字符集轉換的流程。使用者通過mysql命令列(如果是遠端連線:securecrt),敲入命令「insert into t values(1,』小明』)」,字串』小明』在流轉過程中二進位制儲存內容。
a) 使用者採用的客戶端為utf8字符集,character_set_client=gbk,character_set_connection=gbk, 表t採用gbk字符集。
由於character_set_client、character_set_connection和表字符集均為gbk,不涉及編碼轉換。因此,表雖然為字符集雖然為gbk,但「小明」的編碼並非為gbk編碼的二進位製流,而是utf8的二進位製流,兩個漢字占用了6個位元組,而讀取則是乙個逆向的過程,不涉及到編碼轉換,查詢依然能正確返回「小明」。
b) 在a)的情況下,改變character_set_client的設定為utf8,查詢插入的值。
可以看到返回的值是「灝忔槑」, 這是由於表的字符集是gbk,而客戶端請求是utf8,那麼server將二進位製流e5b08fe6988e對應的gbk漢字「灝忔槑」轉為utf8漢字對應的二進位製流e7818fe5bf94e6a791,因此查詢結果在securecrt就顯示為「灝忔槑」,即通常我們所謂的亂碼。
c) 在b)的情況下,設定securecrt的字符集為gbk,看看securecrt字符集設定對結果影響
可以看到返回的是另外一組字元「鐏忓繑妲�」,整個流轉過程與b)一樣,只是在第一步發生了位元組流轉換,設定securecrt字符集編碼,只是改變了顯示方式。
字符集相關的sql語句
1) 檢視字符集編碼設定
show variables like 『%2) 設定字符集編碼character
%』
set names ***;這個語句相當於設定了client的字符集,主要包含3個系統變數,character_set_client,character_set_connection和character_set_results。
3) 修改資料庫字符集
alter這個語句只修改庫的字符集,影響後續建立的表的預設定義;對於已建立的表的字符集不受影響。database databasename character
set ***;
4) 修改表的字符集
alter這個語句只修改表的字符集,影響後續該錶新增列的預設定義,已有列的字符集不受影響。table tablename character
set ***;
alter這個語句同時修改表字符集和已有列字符集,並將已有資料進行字符集編碼轉換。table tablename convert
tocharacter
set ***;
5) 修改列字符集
alter6) 查詢字元的二進位制編碼table `table_name` modify column `column_name` character
set ***
select hex(col_name) from對於gbk的表,如果查出來乙個字元占用了3個位元組,比如圖1這種情況,則肯定是字符集在某個環節設定統一,圖1就是因為客戶端是utf8,而mysqlclient和database都是gbk造成的。table_name;
select length(col_name) from table_name;
mysql預設的字符集latin1
mysql 4.x版本之前預設採用的是latin1字符集(又稱iso-8859-1),latin1字符集編碼方式採用單位元組編碼。拋乙個問題,latin1字符集的表,使用者寫入和讀取漢字是否有問題?答案是只要合理設定,沒有問題。
假設securecrt為utf8,character_set_client和表字符集均設定為latin1,參考第3節的分析,那麼使用者讀取和寫入資料的過程中,並不涉及字符集編碼轉換的問題,將utf8的漢字字元轉為二進位製流寫入database,提取出來後,securecrt再將對應的二進位制解碼為對應的漢字,所以不影響使用者的使用。但是,若character_set_client,character_set_connection,與表字符集設定等不統一,就可能出現亂碼的情況。
標籤:
mysql 字符集 latin1 字符集編碼轉換
字元 字符集 字元編碼
字元是指計算機 中使用的字母 數字 字和符號 包括 1 2 3 a b c 等等。在 ascii 編碼中,乙個英文本母字元儲存需要1個位元組。在 gb 2312 編碼或 gbk 編碼中,乙個漢字 字元儲存需要2個位元組 在utf 8編碼中,乙個英文本母字元儲存需要1個位元組,乙個漢字字元儲存需要3到...
字符集 編碼
字符集概念 1 字符集 可以表示的字元和字元對應計算機位元組碼的對映 2 字元編碼方式 計算機中用來表示和傳輸如前所述字符集中對映的位元組碼的編碼方式。對於ascii和gb2312等字符集,他們在傳輸和計算機表示時的位元組碼不用編碼,直接用字元對應的位元組碼表示。但比如unicode 字符集,就有多...
字符集編碼
喬哥 小萌,聽說你去面試了,怎麼樣啊?小萌 哎 喬哥,你給我講講什麼是字符集和編碼唄,ascii,utf 8,utf 16,utf 32又是啥?喬哥 好的,在搞懂字符集先來講講什麼是編碼吧 在計算機底層,比如說你的名字 小萌 在計算機中並不是文字的形式,而是一串二進位制數字,如 0110011001...