MySQL--字符集

1.字符集概述mysql

  • 簡單的說字符集就是一套文字符號及其編碼、比較規則的集合
  • 20世紀60年代初期,美國標準化組織ANSI發佈了第一個計算機的字符集ASCII(American Standard Code for Information Interchange),後來進一步變成了國際標準ISO-646。這個字符集採用7位編碼,定義了包括大小寫英文字母、阿拉伯數字和標點符號,以及33個控制符號等。

2.Unicode簡述程序員

  • 爲了統一字符編碼,國際標準化組織ISO(International Organization for Standardization)的一些成員國於1984年發起制定新的國際字符集標準,以容納全世界各類語言文字和符號。這個標準最後叫作Universal Multiple-Octet Coded Character Set,簡稱UCS,標準編號則定位ISO-10646。ISO-10646標準採用4字節(32bit)編碼,所以簡稱UCS-4。
  • ISO-10646發佈之後,遭到了部分美國計算機公司的反對。1988年Xerox公司提議指定新的以16爲編碼的統一字符集Unicode,並聯合Apple, IBM, DEC, Sun, Microsoft, Novell等公司成立Unicode協會(The Unicode Consortium),併成立Unicode技術委員會(Unicode Technical Committee),專門負責Unicode文字的蒐集、整理合編碼,並於1991年推出了Unicode 1.0
  • 1991年10月,ISO將Unicode編碼併入ISO-10646的0組0字面,叫作基本多語言文字面(Basic Muiti-lingual Plane,BMP),共有65534個碼位,並根據不一樣用途分爲若干區域。除BMP外的32767個字面又分爲輔助字面和專用字面兩部分,輔助字面用以收錄IS0-10646後續蒐集的各國文字,專用字面供使用者自定義收錄ISO-10646未收錄的文字符號。大部分用戶只是用BMP字面就足夠了,早期的ISO-10646標準也只要求實現BMP字面,這樣只須要2字節來編碼就足夠了,Unicode也正是這麼作的,這叫作ISO-10646編碼的基本面形式,簡稱爲UCS-2編碼,UCS-2編碼轉換成UCS-4編碼也很容易,只要在前面加兩個取值爲0的字節便可
  • Unicode雙字節編碼方式比起ISO-10646的4字節原始編碼來講,在節省內存和處理時間上都具備優點,這也是Unicode編碼方式更流行的緣由。若是須要使用ISO-10646 BMP字面意外的文字,Unicode提出了名爲UTF-16或代理法的解決方案,UTF是UCS/Unicode Transformation Format的縮寫。UTF-16的解決辦法是:對BMP字面的編碼保持二字節不變,對其餘字面的文字按必定規則將其32位編碼轉換爲兩個16位的Unicode編碼,供兩個字節的取值範圍分別限定爲0XD800~0xDBFF和0xDC00~0xDFFF,所以,UTF-16共有( 4 * 256 ) * ( 4  * 256 ) = 1048576 個碼位
  • 雖然UTF-16解決了ISO-10646除BMP外第1~15字面的編碼問題,但當時的計算機和網絡仍是ASCII的天下,只能處理單字節數據流,UTF-16在離開Unicode環境後,在傳輸和處理中都存在問題。因而Unicode又提出了名爲UTF-8的解決方案,UTF-8按必定規則將一個ISO-10646或Unicode字元碼轉換成1~4個字節的編碼,其中將ASCII碼(0~0x7F)轉換成單字節編碼,也就是嚴格兼容ASCII字符集;UTF-8的2字節編碼,用以轉換ISO-10646標準0x0080~0x07FF的UCS-4原始碼;UTF-8的3字節編碼,用以轉換ISO-10646標準0x0800~0xFFFF的UCS-4原始碼;UTF-8的4字節編碼,用以轉換ISO-10646標準0X00010000~0001FFFF的UCS-4原始碼。
  • ISO-10646只是給每個文字符號分配了一個4字節無符號整數編號(UCS-4),並未規定在計算機中如何去表示這個無符號的整數編號。UTF-16和UTF-8就是其兩種變通表示方式。
  • 如今,Unicode和ISO-10646通常指的是同一個東西
  • UTF-16和UTF-32因字節序的不一樣,又有了UTF-16BE(B一個Endian), UTF-16LE(Little Endian), UTF-32BE(Big Endian), UTF-32LE(Little Endian)等

 

3.漢字及一些常見的字符集sql

  • GB 2312-80:全稱《信息交換用漢字編碼字符集 基本集》,於1980年發佈。根據ISO/IEC 2022提供的字符編碼擴充規範,造成雙字節編碼的字符集。收錄了經常使用漢字6763個和非漢字圖形符號682個
  • GB13000:全稱《信息技術 通用多八位編碼字符集(UCS) 第一部分:體系結構與基本多文種平面》,於1993年發佈、根據ISO/IEC 10646-1:1993,在CJK(中日韓簡稱)統一漢字區和CJK統一漢字擴充區A,除收錄GB 2312-80外,還收錄了第1,3,5,7輔助集的所有漢字,宮27474個,以及一些偏旁部首等。但GB13000退出後,幾乎沒有獲得業界的支持,也就成了一個形式上的標準
  • GBK:全稱《漢字內碼擴展規範》 1.0版,發佈於1995年。GBK在GB2312內碼系統上進行了擴充,收錄了GB 13000.1-1993的所有20902個CJK統一漢字,包括GB2312的所有6763個漢字。此外,他增補編碼了52個漢字,13個漢字結構符(在ISO/IEC 10646.1:2000中稱爲表意文字描述符)和一些經常使用部首與漢字部件。在GBK內碼系統中,GB 2312漢字所在碼位保持不變,這樣,保證了GBK對GB 2312的徹底兼容。同時,GBK內碼與GB13000.1代碼一一對應,爲GBK向GB 13000.1的轉換提供瞭解決辦法。有意思的是GBK並非一個強制性的國家標準,只是一個行業指導規範,並無強制力,但因爲獲得了Microsoft Windows95的支持而大爲流行
  • GB 18030:全稱《信息技術信息交換用漢字編碼字符集、基本集的擴充》,發佈於2000年。根據ISO/IEC 10646-1:2000,收錄了ISO/IEC 10646.1:2000所有27848個CJK統一漢字,13個表意文字描述符、部分漢字部首和部件、歐元符號等。GB 18030採用2字節或4字節編碼,其二字節編碼部分與GBK保持一致,所以,GB18030SHI GBK的超集,也徹底與GB 13000向上兼容,制定GB 18030也是爲了解決GBK強制力不夠的問題

 

經常使用字符集比較數據庫

字符集 是否認長 編碼方式 其餘說明
ASCII 單字節7位編碼 最先的奠定性字符集
ISO-8859-1/latin1 單字節8位編碼 西歐字符集,常常被一些程序員用來轉碼
GB 2312-80 雙字節編碼 早起標準,不推薦再使用
GBK 雙字節編碼 雖然不是國標,但支持的系統很多
GB 18030 2字節或4字節編碼 開始有一些支持,但數據庫支持的還少見
UTF-32 4字節編碼 UCS-4原始編碼,目前不多采用
UCS-2 2字節編碼 Windows2000內部用UCS-2
UTF-16 2字節編碼或4字節編碼 Java和Windows XP/NT等內部使用UTF-16
UTF-8 1~4字節編碼

互聯網和UNIX/Linux普遍支持的Unicode字符集;MySQLServer也使用UTF-8緩存

 

 

4.選擇合適的字符集服務器

  • 對數據庫來講,字符集更加劇要,由於數據庫存儲的數據大部分都是各類文字,字符集對數據庫的存儲、處理性能,以及往後系統的移植、推廣都會有影響
  • MySQL目前支持幾十種字符集,包括UCS-2, UTF-16, UTF-16TE, UTF-32, UTF-8和utfmb64等Unicode字符集
  • 知足應用支持語言的需求,若是應用要處理各類各樣的文字,或者將發佈到使用不一樣漢語言的國家和地區,就應該選擇Unicode字符集、對MySQL來講,目前就是UTF-8
  • 若是應用中涉及已有數據的導入,就要充分考慮數據庫字符集對已有數據的兼容性。
  • 若是數據庫只須要支持通常中文數據量很大,性能要求也很高,那就應該選擇雙字節定長編碼的中文字符集,好比GBK。由於對UTF-8而言,GBK比較小,每一個漢字只佔2個字節,而UTF-8漢字編碼須要3個字節,這樣能夠減小磁盤I/O、數據庫Cache以及網絡傳輸的時間,從而提升性能。相反,若是應用主要處理英文字符,僅有少許漢字數據,那麼選擇UTF-8更好,由於GBK、UCS-二、UTF-16的西文字符編碼都是2個字節,會形成不少沒必要要的開銷
  • 若是數據庫須要作大量的字符運算,如比較、排序等,那麼選擇定長字符集可能更好,由於定長字符集的處理速度要比變長字符集的處理速度快
  • 若是全部客戶端程序都支持相同的字符集,則應該優先選擇該字符集做爲數據庫字符集,這樣能夠避免因字符集轉換帶來的性能開銷和數據損失

 

5.MySQL支持的字符集簡介網絡

  • MySQL服務器能夠支持多種字符集,在同一臺服務器、同一個數據庫甚至同一個表的不一樣字段均可以指定使用不一樣的字符集,相比Oracle等其餘數據庫管理系統,在同一個數據庫只能使用相同的字符集,MySQL明顯存在很大的靈活性。
  • 查看全部可用的字符集的命令
          SHOW CHARACTER SET
  • 顯示全部的字符集和該字符集默認的校對規則
          DESC information_schema.character_set
  • MySQL的字符集包括字符集(CHARACTER)和校對規則(COLLAION)兩個概念。其中字符集用來定義MySQL存儲字符串的方式,校對規則用來定義比較字符串的方式。字符集和校對規則是一對多的關係,MySQL支持30多種字符集的70多種校對規則。每一個字符集至少對應一個校對規則,能夠用
          SHOW COLLATION LIKE '***'
        或經過表 information_schema.COLLATIONS來查看相關字符集的校對規則
    校對規則命名約定:他們以其相關的字符集名開始,一般包括一個語言名,而且以_ci(大小寫不敏感),_cs(大小寫敏感),_bin(二元,即比較是基於字符編碼的值而與language無關)結束

 

6.MySQL字符集的設置性能

  • MySQL的字符集和校對規則有4個級別的默認設置:服務器級、數據庫級、表級、字段級。他們分別在不一樣的地方設置,做用也不相同
  • 服務器字符集和校對規則
    服務器字符集和校對規則,能夠在MySQL服務啓動的肯定。
        能夠在 my.cnf 中設置
            character-set-server=gbk
        或者在啓動選項中指定
            mysqld --character-set-server=gbk
        或者在編譯時指定
            cmake . -DEFAULT_CHARSET=gbk
    若是沒有特別的指定服務器字符集,那麼默認使用latin1做爲服務器字符集。上面3種設置的方式都只制定了字符集,沒有指定校對規則,這樣意味着使用該字符集默認的校對規則。若是要使用該字符集非默認的校對規則,則須要在指定字符集的同時指定校對規則。
    查詢當前服務器的字符集和校對規則
        SHOW VARIABLES LIKE 'character_set_server'
  • 數據庫字符集和校對規則
    數據庫的字符集和校對規則在建立數據庫的時候指定,也能夠在建立完數據庫後經過ALTER DATABASE命令進行修改。須要注意的是,若是數據庫裏已經存在數據,由於修改字符集並不能將已有的數據按照新的字符集進行存放,因此不能經過修改數據庫的字符集直接修改數據的內容。
    設置數據庫字符集的規則以下:
        若是指定了字符集和校對規則。則使用指定的字符集和校對規則
        若是指定了字符集沒有指定校對規則,則使用指定字符集的默認校對規則
        若是指定了校對規則但未指定字符集,則字符集使用與該校對規則關聯的字符集
        若是沒有指定字符集和校對規則,則使用服務器字符集和校對規則做爲數據庫的字符集和校對規則
    推薦在建立數據庫時明確指定字符集和校對規則,避免受到默認值的影響。
    顯示當前數據庫默認的字符集和校對規則
        SHOW VARIABLES LIKE 'character_set_database'
        SHOW VARIABLES LIKE 'collation_database'
  • 表字符集和校對規則
    表的字符集和校對規則在建立表的時候指定,能夠經過ALTER TABLE 命令進行修改,一樣,若是表中已有記錄,修改字符集對原有的記錄並無影響,不會按照新的字符集進行存放。表的字段仍然使用原來的字符集。
    設置表的字符集的規則
        若是指定了字符集和校對規則。則使用指定的字符集和校對規則
        若是指定了字符集沒有指定校對規則,則使用指定字符集的默認校對規則
        若是指定了校對規則但未指定字符集,則字符集使用與該校對規則關聯的字符集
        若是沒有指定字符集和校對規則,則使用數據庫字符集和校對規則做爲數據庫的字符集和校對規則
    推薦在建立表的時候明確指定字符集和校對規則,以免受到默認值得影響。
    顯示錶的字符集和校對規則
        SHOW CREATE TABLE table_name
  • 列字符集和校對規則
    MySQL能夠定義列級別的字符集和校對規則,主要是針對相同的表不一樣字符須要使用不一樣的字符集狀況,應該說通常遇到這種狀況的概率比較小,這只是MySQL提供給咱們一個靈活設置的手段。
    列字符集和校對規則的定義能夠在建立表時指定,或者在修改表時調整,若是在建立表的時候沒有特別指定字符集和校對規則,則默認使用表的字符集和校對規則。
  • 鏈接字符集和校對規則
    上面4種設置方式,肯定的是數據保存的字符子和校對規則,對於實際應用訪問來講,還存在客戶端和服務器之間交互的字符集和校對規則的設置。
    對於客戶端和服務器的交互操做,MySQL提供了3個不一樣的參數:
        character_set_client    客戶端
        character_set_connection  鏈接
        character_set_results    返回結果的字符集
    一般狀況下,這3個字符集應該是相同的,才能夠確保用戶寫入的數據能夠正確的讀出,特別是對於中文字符,不一樣的寫入字符集和返回結果字符集將致使寫入的記錄不能正確的讀出。
    一般狀況下,不會單個的設置這3個參數,能夠經過如下命令:
        SET NAMES ***
    來設置鏈接的字符集和校對規則,這個命令能夠同時修改這3個參數的值。使用這個方法修改鏈接的字符集和校對規則,須要應用每次鏈接數據庫後都執行這個命令。
    另外一個更簡便的方法,是在my.cnf中設置如下語句:
        t-character-set=gbk
    這樣服務器啓動後,全部鏈接默認就是使用GBK字符集進行鏈接的,而不須要在程序中在執行set names命令。
    另外,字符串常量的字符集也是由character_set_connection參數來指定的
    能夠經過 [_charset_name] 'string' [COLLATE collation_name] 命令強制字符串的字符集和校對規則。一般狀況下,基本不須要用戶強制指定字符串字符集。

 

7.字符集的修改步驟ui

  • 若是在應用開始階段沒有正確的設置字符集,在運行一段時間之後才發現存在不能知足要求須要調整,又不想丟棄這段時間的數據,那麼就須要進行字符集的修改。
    字符集修改不能直接經過ALTER TABLE CHARACTER SET *** 或 ALTER TABLE table_name character set *** 命令進行,這兩個命令都沒有更新已有記錄的字符集,而只是對建立的表或者記錄生效。已有記錄的字符集調整,須要先將數據導出,通過適當的調整從新導入後纔可完成。
  • 選擇目標字符集的時候,要注意最好是源字符集的超集,或者肯定比源字符集的字庫更大,不然若是目標字符集的字符小於源字符集的字庫,那麼目標字符集中不支持的字符導入後會變成亂碼,丟失一部分數據。實例:模擬將latin1字符集的數據庫修改爲GBK字符集的數據庫的過程1) 導出表結構      mysqldump -uroot -p --default-character-set=gbk -d databasename > createtab.sql        其中--default-character-set=gbk表示設置以什麼字符集鏈接,-d表示只導出表結構,不導出數據2) 手工修改createtab.sql中表結構定義中的字符集爲新的字符集3) 確保記錄再也不更新,導出全部記錄      mysqldump -uroot -p --quick --no-create-info --extended-insert --default-character-set=latin1 databasename > data.sql      --quick:該選項用於轉出打的表。他強制mysqldump從服務器一次一行地檢索表中的行而不是檢索全部行,並在輸出前將他緩存到內存中      --extended-insert:使用包括幾個VALUES列表的多行INSERT語法。這樣使轉出文件更小,重載文件時能夠加速插入      --no-create-info:不導出每一個轉儲表的CREATE TABLE語句      --default-character-set=latin1:按照原有的字符集導出全部數據就,這樣導出的文件中,全部中文都是可見的。不會保存成亂碼4) 打開data.sql,將SET NAMES latin1修改爲SET NAMES gbk5) 使用新的字符集建立新的數據庫      CREATE DATABASE database_name      DEFAULT CHARSET charset_name6) 建立表,執行 createtab.sql      mysql -uroot -p databasename < createtab.sql7) 導入數據,執行data.sql      mysql -uroot -p databasename < data.sql
相關文章
相關標籤/搜索