天天看點

mysql字元集介紹_MySQL字元集介紹及亂碼解決方法

MySQL自4.1版本推出之後由于中文的特殊性帶來的亂碼問題也随在網際網路行業出現。

主要原因就是不同字元集編碼不同而産生的。本文簡要介紹字元集相關知識及部分亂碼情況的解決方式。

一、字元集本概念

字元集的基本概念如下 :

•字元(Character)是指人類語言中最小的表義符号。例如’A’、’B’等

•給定一系列字元,對每個字元賦予一個數值,用數值來代表對應的字元,這一數值就是字元的編碼(Encoding)。例如,我們給字元’A’賦予數值0,給字元’B’賦予數值1,則0就是字元’A’的編碼

•給定一系列字元并賦予對應的編碼後,所有這些字元和編碼對組成的集合就是字元集(Character Set)。例如,給定字元清單為{’A’,’B’}時,{’A’=>0, ‘B’=>1}就是一個字元集

•字元序(Collation)是指在同一字元集内字元之間的比較規則

•确定字元序後,才能在一個字元集上定義什麼是等價的字元,以及字元之間的大小關系

•每個字元序唯一對應一種字元集,但一個字元集可以對應多種字元序,其中有一個是預設字元序(Default Collation)

•MySQL中的字元序名稱遵從命名慣例:以字元序對應的字元集名稱開頭;以_ci(表示大小寫不敏感)、_cs(表示大小寫敏感)或_bin(表示按編碼值比較)結尾。例如:在字元序“utf8_general_ci”下,字元“a”和“A”是等價的

二、常見字元集

1)ASCII

ASCII是英文American Standard Code for Information Interchange的縮寫,美國标準資訊交換代碼是由美國國家标準學會(American National Standard Institute , ANSI )制定的,标準的單位元組字元編碼方案,用于基于文本的資料。是基于拉丁字母的一套電腦編碼系統。它主要用于顯示現代英語和其他西歐語言。它是現今最通用的 單位元組編碼系統,并等同于國際标準ISO/IEC 646。

ASCII 碼使用指定的7 位或8 位二進制數組合來表示128 或256 種可能的字元。标準ASCII 碼也叫基礎ASCII碼,使用7 位二進制數來表示所有的大寫和小寫字母,數字0 到9、标點符号, 以及在美式英語中使用的特殊控制字元。

2)GBK

GBK即漢字内碼擴充規範,K為擴充的漢語拼音中“擴”字的聲母。英文全稱Chinese Internal Code Specification。GBK編碼标準相容GB2312,共收錄漢字21003個、符号883個,并提供1894個造字碼位,簡、繁體字融于一庫。

GB2312碼是中華人民共和國國家漢字資訊交換用編碼,全稱《資訊交換用漢字編碼字元集——基本集》,1980年由國家标準總局釋出。基本集共收入漢字 6763個和非漢字圖形字元682個,通行于中國大陸。新加坡等地也使用此編碼。GBK是對GB2312-80的擴充,也就是CP936字碼表 (Code Page 936)的擴充(之前CP936和GB 2312-80一模一樣)。

3)latin1

Latin1是ISO-8859-1的别名,有些環境下寫作Latin-1。

ISO-8859-1

ISO-8859-1編碼是單位元組編碼,向下相容ASCII,其編碼範圍是0x00-0xFF,0x00-0x7F之間完全和ASCII一緻,0x80-0x9F之間是控制字元,0xA0-0xFF之間是文字元号。

ISO-8859-1收錄的字元除ASCII收錄的字元外,還包括西歐語言、希臘語、泰語、阿拉伯語、希伯來語對應的文字元号。歐元符号出現的比較晚,沒有被收錄在ISO-8859-1當中。

因為ISO-8859-1編碼範圍使用了單位元組内的所有空間,在支援ISO-8859-1的系統中傳輸和存儲其他任何編碼的位元組流都不會被抛棄。換言之,把其他任何編碼的位元組流當作ISO-8859-1編碼看待都沒有問題。這是個很重要的特性,MySQL資料庫預設編碼是Latin1就是利用了這個 特性。ASCII編碼是一個7位的容器,ISO-8859-1編碼是一個8位的容器。

4)UTF-8

UTF-8(8-bit Unicode Transformation Format)是一種針對Unicode的可變長度字元編碼,又稱萬國碼。由Ken Thompson于1992年建立。現在已經标準化為RFC 3629。UTF-8用1到4個位元組編碼UNICODE字元。用在網頁上可以同一頁面顯示中文簡體繁體及其它語言(如日文,韓文)

UTF-8以位元組為機關對Unicode進行編碼。

UTF-8的特點是對不同範圍的字元使用不同長度的編碼。對于0x00-0x7F之間的字元,UTF-8編碼與ASCII編碼完全相同。UTF-8 編碼的最大長度是4個位元組。

從上表可以看出,4位元組模闆有21個x,即可以容納21位二進制數字。Unicod的最大碼位0x10FFFF也隻有21 位。

三、MySQL字元集轉換過程

1. MySQL Server收到請求時将請求資料從character_set_client轉換為character_set_connection

2. 進行内部操作前将請求資料從character_set_connection轉換為内部操作字元集,其确定方法如下:

1) 使用每個Column的CHARACTER SET設定值;

2) 如未設定Column的Character SET,則使用對應表的DEFAULT CHARACTER SET設定值

3) 如Column、Table均未設地Charater SET,則使用對應資料庫的DEFAULT CHARACTER SET設定值

4) 如Column、Table、Database均未設地Charater SET,則使用character_set_server設定值。

3. 将操作結果從内部操作字元集轉換為character_set_results

mysql字元集介紹_MySQL字元集介紹及亂碼解決方法

四、中文亂碼現象

Mysqldump導入亂碼

mysql字元集介紹_MySQL字元集介紹及亂碼解決方法

Load data導入亂碼

mysql字元集介紹_MySQL字元集介紹及亂碼解決方法

五、程式及MySQL字元集配置情況

出現亂碼情況,首先确認寫入程式使用的字元集,MySQL使用的字元集

MySQL使用的字元集情況

通過SHOW VARIABLES LIKE ‘character%’,在上面例子中通過語句獲得字元集設定情況如下:

mysql字元集介紹_MySQL字元集介紹及亂碼解決方法

Mysqldump導入亂碼原因 :

1、首先确認mysqldump –help或檢視備份檔案頭部資訊确認預設字元集

在上例中通過mysqldump –help檢視

mysql字元集介紹_MySQL字元集介紹及亂碼解決方法

通過備份檔案檢視

mysql字元集介紹_MySQL字元集介紹及亂碼解決方法

2、通過 mysql –help 确認導入字元集

mysql字元集介紹_MySQL字元集介紹及亂碼解決方法

導入的兩種情況如下

1)不修改備份檔案,導入由于sql檔案中存在set names utf8,則導入後字元集使用的依然是utf8,在系統預設顯示字元集為gbk的情況下,則顯示為亂碼,此時則需要使用set names utf8 才能正常顯示字元

2)修改備份檔案,導入前将sql中的set names utf8 去除,在mysql預設字元集為gbk的情況下導入後字元集為gbk,此時mysql顯示字元集為 gbk,兩者一緻,則顯示正常

Load data導入亂碼原因

mysql字元集介紹_MySQL字元集介紹及亂碼解決方法

對于load data導入亂碼問題的具體解釋在官方文檔中有提及,請參考:

mysql字元集介紹_MySQL字元集介紹及亂碼解決方法

這些是無法影響到導入結果的,是以應使用Load 自身的字元集參數來進行資料導入,如下方式:

mysql字元集介紹_MySQL字元集介紹及亂碼解決方法

六、總結

1、編譯安裝MySQL的時候指定DEFAULT_CHARSET=[charset] 與寫入程式保持一緻

2、my.cnf中字元集設定與寫入程式保持一緻

3、導入資料時,将導入程式與資料庫的連結配置為與資料庫字元集一緻

4、load data需要在語句中設定字元集參數