字符集(Character set)
定義: 是多個字符(英文字符,漢字字符,或者其他國家語言字符)的集合,字符集種類較多,每個字符集包含的字符個數不同。
特點:
ASCII字符集:基於羅馬字母表的一套字符集,它採用1個字節的低7位表示字符,高位始終爲0。
LATIN1字符集:相對於ASCII字符集做了擴展,仍然使用一個字節表示字符,但啓用了高位,擴展了字符集的表示範圍。
GBK字符集:支持中文,字符有一字節編碼和兩字節編碼方式。
UTF8字符集:Unicode字符集的一種,是計算機科學領域裏的一項業界標準,支持了所有國家的文字字符,utf8採用1-4個字節表示字符。
MySql與字符集
只要涉及到文字的地方,就會存在字符集和編碼方式。MySQL系統變量值:
show variables like '%character%'
正確使用字符集
數據庫服務端的字符集具體要看存儲什麼字符
參數 | 說明 |
---|---|
character_set_server | 默認內部操作字符集 |
character_set_client | 客戶端來源數據使用的字符集 |
character_set_connection | 連接層字符集 |
character_set_results | 查詢結果字符集 |
character_set_database | 當前數據庫的默認字符集 |
character_set_results | 查詢結果字符集 |
character_set_system | 系統元數據(字段名等)字符集 |
以上這些參數如何起作用:
- 庫、表、列字符集的由來
①建庫時,若未明確指定字符集,則採用character_set_server
指定的字符集。
②建表時,若未明確指定字符集,則採用當前庫所採用的字符集。
③新增時,修改表字段時,若未明確指定字符集,則採用當前表所採用的字符集。 - 更新、查詢涉及到得字符集變量
更新流程字符集轉換過程:character_set_client
–>character_set_connection
–>表字符集。
查詢流程字符集轉換過程:表字符集–>character_set_result
- character_set_database
當前默認數據庫的字符集,比如執行use xxx後,當前數據庫變爲xxx,若xxx的字符集爲utf8,那麼此變量值就變爲utf8(供系統設置,無需人工設置)。
MySQL客戶端與字符集
1.對於輸入來說:
客戶端使用的字符集必須通過character_set_client
、character_set_connection
體現出來:
①在客戶端對數據進行編碼(Linux:utf8、windows:gbk)
②MySQL接到SQL語句後(比如insert),發現有字符,詢問客戶端通過什麼方式對字符編碼:客戶端通過character_set_client
參數告知MySQL客戶端的編碼方式(所以此參數需要正確反映客戶端對應的編碼)
③當MySQL發現客戶端的client所傳輸的字符集與自己的connection不一樣時,會將client的字符集轉換爲connection的字符集
④MySQL將轉換後的編碼存儲到MySQL表的列上,在存儲的時候再判斷編碼是否與內部存儲字符集(按照優先級判斷字符集類型)上的編碼一致,如果不一致需要再次轉換
2.對於查詢來說:
客戶端使用的字符集必須通過character_set_results
來體現,服務器詢問客戶端字符集,通過character_set_results將結果轉換爲與客戶端相同的字符集傳遞給客戶端。(character_set_results默認等於character_set_client)
MySQL字符編碼轉換原理:
問:若character_set_client
爲UTF8,而character_set_database
爲GBK,則會出現需要進行編碼轉換的情況,字符集轉換的原理是什麼?
答:假設gbk字符集的字符串“你好”,需要轉爲utf8字符集存儲,實際就是對於“你好”字符串中的每個漢字去utf8編碼表裏面查詢對應的二進制,然後存儲。
圖解字符集轉換過程:
①MySQL Server收到請求時將請求數據從character_set_client轉換爲character_set_connection;
②進行內部操作前將請求數據從character_set_connection轉換爲內部操作字符集,步驟如下
-
使用每個數據字段的CHARACTER SET設定值;
-
若上述值不存在,則使用對應數據表的DEFAULT CHARACTER SET設定值;
-
若上述值不存在,則使用對應數據庫的DEFAULT CHARACTER SET設定值;
-
若上述值不存在,則使用character_set_server設定值;
③將操作結果從內部操作字符集轉換爲character_set_results。
字符集常見處理操作
1.查看字符集編碼設置
show variables like '%character%';
2.設置字符集編碼
set names 'utf8';
這相當於同時執行了一下設置:
set character_set_client = utf8;
set character_set_results = utf8;
set character_set_connection = utf8;
修改數據庫字符集
alter database database_name character set xxx;
只修改庫的字符集,影響後續創建的表的默認定義;對於已創建的表的字符集不受影響。(一般在數據庫實現字符集即可,表和列都默認採用數據庫的字符集)
.修改表的字符集
mysql> alter table table_name character set xxx;
只修改表的字符集,影響後續該表新增列的默認定義,已有列的字符集不受影響。
mysql> alter table table_name convert to character set xxx;
同時修改表字符集和已有列字符集,並將已有數據進行字符集編碼轉換。
修改列字符集
格式:
ALTER TABLE table_name MODIFY
column_name {CHAR | VARCHAR | TEXT} (column_length)
[CHARACTER SET charset_name]
[COLLATE collation_name]
mysql> alter table table_name modify col_name varchar(col_length) character set xxx;
字符集的正確實踐:
MySQL軟件工具本身是沒有字符集的,主要是因爲工具所在的OS的字符集(Windows:gbk、Linux:utf8),所以字符集的正確實踐非常重要:
1.對於insert來說,character_set_client、character_set_connection相同,而且正確反映客戶端使用的字符集(就是設置成客戶端對應的字符集)
2.對於select來說,character_set_results正確反映客戶端字符集
4.字符集轉換最多發生一次,這就要求character_set_client、character_set_connection相同
5.所有的字符集轉換都發生在數據庫端
綜述:
1、建立數據庫的時候注意字符集(gbk、utf8);
2、連接數據庫以後,無論是執行dml還是select,只要涉及到varchar、char列,就需要設置正確的字符集參數
ps:dml 數據操縱語言,insert,delete,update,select等.ddl 數據定義語言 如 create,alter和drop
校對規則collation校對
字符集是一套符號和對應的編號,查看數據庫支持的所有字符集(charset):
mysql> show character set;
校對規則(collation):
是在字符集內用於字符比較和排序的一套規則,比如有的規則區分大小寫,有的則無視。
mysql> create table t1(id int,name varchar(20)); #t1建表沒有指定校對規則
mysql> show collation; #查看數據庫支持的所有校對規則
mysql> show variables like 'collation_%'; #查看當前字符集和校對規則設置
校對規則特徵:
①兩個不同的字符集不能有相同的校對規則;
②每個字符集有一個默認校對規則;
③存在校對規則命名約定:以其相關的字符集名開始,中間包括一個語言名,並且以_ci(大小寫不敏感)、_cs(大小寫敏感)或_bin(二元)結束。
ps:系統使用utf8字符集,若使用utf8_bin校對規則執行SQL查詢時區分大小寫,使用utf8_general_ci不區分大小寫(默認的utf8字符集對應的校對規則是utf8_general_ci)。
示例:
mysql> create table t2(id int,name varchar(20)) character set=gbk collate=gbk_bin; #t2建表指定校對規則(區分大小寫)