字符集是一套符號和編碼,校驗規則(collation)是在字符集內用於比較字符的一套規則,即字符集的排序規則。MySQL可使用多種字符集和檢驗規則來組織字符。mysql
MySQL服務器能夠支持多種字符集,在同一臺服務器,同一個數據庫,甚至同一個表的不一樣字段均可以指定使用不一樣的字符集,相比oracle等其餘數據庫管理系統,在同一個數據庫只能使用相同的字符集,MySQL明顯存在更大的靈活性。web
每種字符集均可能有多種校對規則,而且都有一個默認的校對規則,而且每一個校對規則只是針對某個字符集,和其餘的字符集麼有關係。
在MySQL中,字符集的概念和編碼方案被看作是同義詞,一個字符集是一個轉換表和一個編碼方案的組合。sql
Unicode(Universal Code)是一種在計算機上使用的字符編碼。Unicode 是爲了解決傳統的字符編碼方案的侷限而產生的,它爲每種語言中的每一個字符設定了統一而且惟一的二進制編碼,以知足跨語言、跨平臺進行文本轉換、處理的要求。Unicode存在不一樣的編碼方案,包括Utf-8,Utf-16和Utf-32。Utf表示Unicode Transformation Format。數據庫
下面的SQL命令均可以查看MySQL數據庫支持字符集show character set;
select * from information_schema.character_sets;
咱們使用第一條命令行舉例,執行命令後能夠看到下圖所示的結果:windows
查詢MySQL支持的全部校對規則:show collation;
查詢MySQL支持的utf8校對規則:show collation like 'utf8%';
固然也可使用select語句查詢:select * from information_schema.collations where collation_name like 'utf8%';
咱們使用第一條命令舉例,執行命令後能夠看到下圖所示的結果:瀏覽器
執行show variables like 'character%';
能夠查看當前數據庫使用的字符集,以下圖所示:服務器
解釋一下上圖中變量名錶明的意思:
character_set_client:客戶端請求數據的字符集
character_set_connection:客戶機/服務器鏈接的字符集
character_set_database:默認數據庫的字符集,不管默認數據庫如何改變,都是這個字符集;若是沒有默認數據庫,那就使用 character_set_server指定的字符集,這個變量建議由系統本身管理,不要人爲定義。
character_set_filesystem:把os上文件名轉化成此字符集,即把character_set_client轉換character_set_filesystem,默認binary是不作任何轉換的併發
character_set_results:結果集,返回給客戶端的字符集
character_set_server:數據庫服務器的默認字符集
character_set_system:系統字符集,這個值老是utf8,不須要設置。這個字符集用於數據庫對象(如表和列)的名字,也用於存儲在目錄表中的函數的名字。oracle
執行show variables like 'collation%';
能夠查看當前數據庫使用的校對規則,以下圖所示:函數
解釋一下上圖中變量名錶明的意思:
collation_connection:當前鏈接的字符集。
collation_database:當前日期的默認校對。每次用USE語句來「跳轉」到另外一個數據庫的時候,這個變量的值就會改變。若是沒有當前數據庫,這個變量的值就是collation_server變量的值。
collation_server:服務器的默認校對。
排序方式的命名規則爲:字符集名字語言後綴,其中各個典型後綴的含義以下:
1)_ci:不區分大小寫的排序方式
2)_cs:區分大小寫的排序方式
3)_bin:二進制排序方式,大小比較將根據字符編碼,不涉及人類語言,所以_bin的排序方式不包含人類語言
MySQL字符集設置分爲兩類:
1)建立對象的默認值。
2)控制server和client端交互通訊的配置。
字符集合校對規則有4個級別的默認設置:
1)服務器級別;
2)數據庫級別;
3)表級別、列級別;
4)鏈接級別。
更低級別的設置會集成高級別的設置。
這裏有一個通用的規則:先爲服務器或者數據庫選擇一個合理的字符集,而後根據不一樣的實際狀況,讓某個列選擇本身的字符集。
大部分MySQL客戶端都不具有同時支持多種字符集的能力,每次都只能使用一種字符集。
客戶和服務器之間的字符集轉換工做是由以下幾個MySQL系統變量控制的。
1)character_set_server:MySQL服務端默認字符集。
2)character_set_database:數據庫默認字符集。
3)character_set_client:MySQL服務端假定客戶端發送的查詢使用的字符集。
4)character_set_connection:MySQL服務端接收客戶端發佈的查詢請求後,將其轉換爲character_set_connection變量指定的字符集。
5)character_set_results:MySQL服務端把結果集和錯誤信息轉換爲character_set_results指定的字符集,併發送給客戶端。
6)character_set_system:系統元數據(字段名等)字符集
還有以collation_開頭的同上面對應的變量,用來描述字符校對規則。
注意事項:
• my.ini中的default_character_set設置隻影響mysql命令鏈接服務器時的鏈接字符集,不會對使用libmysqlclient庫的應用程序產生任何做用!
• 對字段進行的SQL函數操做一般都是之內部操做字符集進行的,不受鏈接字符集設置的影響。
• SQL語句中的裸字符串會受到鏈接字符集或introducer設置的影響,對於比較之類的操做可能產生徹底不一樣的結果,須要當心!
(1)編譯MySQL時,指定了一個默認的字符集,這個字符集是 latin1;
(2)安裝MySQL時,能夠在配置文件 (my.ini) 中指定一個默認的的字符集,若是沒指定,這個值繼承自編譯時指定的;
(3)啓動mysqld時,能夠在命令行參數中指定一個默認的的字符集,若是沒指定,這個值繼承自配置文件中的配置,此時character_set_server被設定爲這個默認的字符集;
(4)當建立一個新的數據庫時,除非明確指定,這個數據庫的字符集被缺省設定爲character_set_server;
(5)當選定了一個數據庫時,character_set_database被設定爲這個數據庫默認的字符集;
(6)在這個數據庫裏建立一張表時,表默認的字符集被設定爲character_set_database,也就是這個數據庫默認的字符集;
(7)當在表內設置一欄時,除非明確指定,不然此欄缺省的字符集就是表默認的字符集;
在建立數據庫的時候就能夠爲數據庫指定字符集和校對規則,SQL命令示例以下:create database dbtest charset=utf8 collate utf8_romanian_ci;
charset=utf8
表示設定數據庫字符集爲utf8
collate utf8_romanian_ci
表示設定數據庫校對規則爲utf8_romanian_ci
咱們能夠經過show create database dbtest
查看建立數據庫的SQL語句,命令執行效果以下圖所示:
注意:建立數據庫分配字符集能夠採用如下幾種語句都行:
charset=utf8;
default charset=utf8;
charset utf8;
default charset utf8;
char set=utf8;
default char set=utf8;
char set utf8;
default char set utf8;
character set=utf8;
default character set=utf8;
character set utf8;
default character set utf8;
咱們能夠通用建立數據庫表的時候爲表指定字符集和校對規則,執行SQL命令以下:
default charset=utf8
表示設置字符集collate utf8_romanian_ci
表示設置校對規則
咱們能夠經過show create table table_charset
查看建立表的SQL語句,命令執行效果以下圖所示:
注意:爲表指定字符集可使用如下幾種方式:
default charset=utf8;
charset=utf8;
default character set=utf8;
character set=utf8;
default char set=utf8;
char set=utf8;
咱們能夠經過建立數據庫表的時候就爲列指定字符集和校對規則,執行SQL命令以下:
語法與設置數據庫表基本上同樣,而後咱們經過下面的SQL命令查看這張表的字符集規則
命令行執行結果以下圖所示
MySQL服務器支持衆多不一樣的字符集,這類字符集可在編譯時和運行時指定。
1)編譯時指定
編譯時可指定默認字符集和默認校對規則,要想同時更改默認字符集和校對規則,要同時使用–with-charset和–with-collation選項。
校對規則必須是字符集的合法校對規則,如如下編譯示例./configure --with-charset=utf8 --with-collation=utf8_romanian_ci
經過configure選項–with-extra-charsets=LIST,能夠定義在服務器中再定義增長字符集。
LIST指下面任何一項:
a.空格間隔的一系列字符集名
b.complex -,以包括不能動態裝載的全部字符集
c.all –,以將全部字符集包括進二進制
編譯示例以下所示./configure --with-charset=utf8 --with-collation=utf8_romanian_ci --with-extra-charsets=all
固然編譯指定通常是在Linux操做系統下執行,在windows下面安裝MySQL通常不作編譯指定。
2)在參數文件my.ini中指定
3)在啓動參數前指定
4)在mysql客戶端登錄時經過–default-character-set指定
5)臨時指定
a)分別指定
mysql> SET character_set_client = utf8;
mysql> SET character_set_connection = utf8;
mysql> SET character_set_database = utf8;
mysql> SET character_set_results = utf8;
mysql> SET character_set_server = utf8;
b)mysql客戶端使用:set names utf8;
等同於
set character_set_client=utf8;
set character_set_connection=utf8;
set character_set_results=utf8;
c)set character set utf8;
等同於
set character_set_client=utf8;
set character_set_results=utf8;
set collation_connection=@@collation_database;
下面介紹下幾個MYSQL命令:
查看數據庫支持的全部字符集show character set;
show char set;
查看當前狀態 裏面包括固然的字符集設置status;
\s;
查看系統字符集設置,包括全部的字符集設置show variables like 'char%';
查看sqlstudy數據庫中表的字符集設置show table status from sqlstudy like '%countries%';
查看錶列的字符集設置,關鍵是在同一個表中,每列能夠設置成不一樣的字符集show full columns from countries;
知道怎麼查看字符集了,下面我來講下如何設置這些字符集
1.修改服務器級
a. 臨時更改,執行下面命令行:SET GLOBAL character_set_server=utf8;
b. 永久更改:
修改my.ini文件
2.修改數據庫級
a. 臨時更改,執行命令行:SET GLOBAL character_set_database=utf8;
b. 永久更改:
改了服務器級就能夠了
3.修改表級,執行命令行:ALTER TABLE table_name DEFAULT CHARSET utf8;
更改了後永久生效
4.修改列級
修改示例:
更改了後永久生效
5.更改鏈接字符集
a. 臨時更改:set names utf8;
b. 永久更改:
修改my.ini文件
1)客戶機沒有正確地設置client字符集,致使原先的SQL語句被轉換成connection所指字符集,而這種轉換,是會丟失信息的,若是client是utf8格式,那麼若是轉換成gb2312格式,這其中一定會丟失信息,反之則不會丟失。必定要保證connection的字符集大於client字符集才能保證轉換不丟失信息。
2)數據庫字體沒有設置正確,若是數據庫字體設置不正確,那麼connection字符集轉換成database字符集照樣丟失編碼,緣由跟上面同樣。
character_set_client:咱們要告訴服務器,我給你發送的數據是什麼編碼?
character_set_connection:告訴字符集轉換器,轉換成什麼編碼?
character_set_results:查詢的結果用什麼編碼?
若是以上三者都爲字符集N,可簡寫爲set names ‘N’;
向默認字符集爲utf8的數據表插入utf8編碼的數據前鏈接字符集設置爲latin1,查詢時設置鏈接字符集爲utf8。
插入時根據MySQL服務器的默認設置,character_set_client、character_set_connection和character_set_results均爲latin1;
插入操做的數據將通過latin1=>latin1=>utf8的字符集轉換過程,這一過程當中每一個插入的漢字都會從原始的3個字節變成6個字節保存;
查詢時的結果將通過utf8=>utf8的字符集轉換過程,將保存的6個字節原封不動返回,產生亂碼
依次執行下面SQL命令
咱們會看到以下的輸出結果
此時修改鏈接編碼,在進行查詢
命令執行後的輸出結果
注意:存儲字符集編碼比插入時字符集大時,若是原封不動返回數據會出現亂碼,不過可經過修改查詢字符集,避免亂碼,即不會丟失數據。
1)首先要明確你的客戶端時候何種編碼格式,這是最重要的(IE6通常用utf8,命令行通常是gbk,通常程序是gb2312)
2)確保你的數據庫使用utf8格式,很簡單,全部編碼通吃。
3)必定要保證connection字符集大於等於client字符集,否則就會信息丟失,好比: latin1 < gb2312 < gbk < utf8,若設置set character_set_client = gb2312,那麼至少connection的字符集要大於等於gb2312,不然就會丟失信息
4)以上三步作正確的話,那麼全部中文都被正確地轉換成utf8格式存儲進了數據庫,爲了適應不一樣的瀏覽器,不一樣的客戶端,你能夠修改character_set_results來以不一樣的編碼顯示中文字體,因爲utf8是大方向,所以web應用是我仍是傾向於使用utf8格式顯示中文的。
老九學堂會員社羣出品
做者:naaman