mysql字符集基礎知識梳理

  接着上一篇繼續來一篇關於mysql字符設置等問題學習筆記,這篇就不說什麼廢話了,直接進入正題,不過仍是感謝十八哥的無私分享!php

  咱們首先看看mysql整個數據存儲和讀取一個流程:mysql

    

  

  鏈接器(connection)sql

         特性:連接客戶端與服務器數據庫

         過程:windows

     客戶端的字節先發給鏈接器,服務器

           鏈接器選擇一種編碼將其轉換,臨時存儲學習

           再次轉換成 服務器西藥的編碼,並正真的存儲在服務器上  編碼

    如今,咱們以mysql這個流程說一下,在存入數據和讀取數據時的編碼轉換。spa

         如圖翻譯

存入數據:

讀取數據:

    A:client:GBK --->   鏈接器接受並轉爲utf8  ---->數據庫服務器和鏈接器編碼相同不用轉碼直接給服務器

    B:client:GBK --->   不轉 ---->鏈接器--->轉碼---->數據庫服務器存儲

    C:client:GBK <--->不轉 <----鏈接器<---轉碼<----數據庫服務器存儲

    以上就是當client和sever編碼不一致存儲讀取時,鏈接器在其中進行轉碼的過程。固然,在client和sever編碼一致時,鏈接器就沒必要轉碼,直接發送數據存儲就能夠了,這裏就不作圖片說明。

  在這個其中就涉及到了client端設置客戶端、鏈接器端、服務器端編碼的問題?

    咱們可能常用這句命令:set names utf8; 但是其中的具體意義是什麼?

         咱們首先看看這條命令:show variables like ‘%char%’

    

mysql> show variables like '%char%';
+--------------------------+-----------------------------------+
| Variable_name            | Value                             |
+--------------------------+-----------------------------------+
| character_set_client     | utf8                              |
| character_set_connection | utf8                              |
| character_set_database   | utf8                              |
| character_set_filesystem | binary                            |
| character_set_results    | utf8                              |
| character_set_server     | utf8                              |
| character_set_system     | utf8                              |
| character_sets_dir       | D:\phpStudy\MySQL\share\charsets\ |
+--------------------------+-----------------------------------+

  

其中的:

         character_set_client       指的就是設置的客戶端編碼

         character_set_connection      指的是鏈接器設置的編碼

         character_set_results          返回數據設置的編碼(這是在取出數據返回到client時設置的編碼)

         那麼,剩下的都是什麼意思?

   character_set_database        默認數據庫的字符集,不管默認數據庫如何改變,都是這個字符集;若是沒有默認數據庫,那就使用 character_set_server指定的字符集,這個變量建議由系統本身管理,不要人爲定義。

         character_set_filesystem        把os上文件名轉化成此字符集,即把 character_set_client轉換character_set_filesystem, 默認binary是不作任何轉換的

         character_set_server               數據庫服務器的默認字符集

         character_set_system    這個值老是utf8,不須要設置,是爲存儲系統元數據的字符集

         character_sets_dir           字符集的文件路徑         

 

  如何設置:

    命令是這樣的格式: set character_set_client=GBK;

    其餘的都是類似的,你們類推便可。

 

  那麼看了上面的mysql> show variables like '%char%';的設置,咱們想知道:爲何有時候我寫的中文會亂碼,不是一致嗎?都是utf8?其實,這是mysql在安裝是的一個設置,咱們真正執行:

    insert into test values(1,’趴在巨人肩上的矮子’)的時候,一切都覺得是UTF8,可是真的就是嘛?

    咱們的windows在中國,系統用的是GBK編碼,其實咱們輸入的這幾個漢字就是GBK編碼的,mysql的整個流程卻都是UTF8,這就固然就亂碼了,咱們能夠看看咱們的client編碼:

  如圖:

    

  因此,咱們就必須設置,讓數據庫知道,客戶端此時要輸入的是GBK,這時就能夠設置

    set character_set_client=GBK;

    固然,你是要 set names GBK; 咱們來看看這條命令的結果,你們就明白了

mysql> set names gbk;
Query OK, 0 rows affected (0.03 sec) mysql> show variables like '%char%'; +--------------------------+-----------------------------------+ | Variable_name | Value | +--------------------------+-----------------------------------+ | character_set_client | gbk | | character_set_connection | gbk | | character_set_database | utf8 | | character_set_filesystem | binary | | character_set_results | gbk | | character_set_server | utf8 | | character_set_system | utf8 | | character_sets_dir | D:\phpStudy\MySQL\share\charsets\ | +--------------------------+-----------------------------------+ 8 rows in set (0.00 sec)

  咱們看到character_set_client 、character_set_connection 、character_set_results   都已經設置成了GBK,那就說明:此時鏈接器、客戶端和返回結果都是GBK,那麼,插入數據時,就是咱們上面流圖的第二種狀況:

     B:client:GBK --->   不轉 ---->鏈接器--->轉碼---->數據庫服務器存儲

  同時,當你須要查看結果時,也不會亂碼,由於character_set_results已是GBK了。這下清楚了吧!

  固然,咱們設置set character_set_results=GBK;這樣只能保證咱們select操做時獲得的漢字數據不會亂碼,若是沒有設置character_set_client,咱們的insert照樣也會亂碼,並且,咱們仔細考慮:當你沒有設置character_set_client時,你的GBK漢字mysql以utf8存了,此時會怎樣?

mysql> show variables like '%char%';
+--------------------------+-----------------------------------+
| Variable_name            | Value                             |
+--------------------------+-----------------------------------+
| character_set_client     | utf8                              |
| character_set_connection | utf8                              |
| character_set_database   | gbk                               |
| character_set_filesystem | binary                            |
| character_set_results    | gbk                               |
| character_set_server     | utf8                              |
| character_set_system     | utf8                              |
| character_sets_dir       | D:\phpStudy\MySQL\share\charsets\ |
+--------------------------+-----------------------------------+
8 rows in set (0.00 sec)

mysql> insert into tb_1 values(6,'來了','男','百度',999,11);
Query OK, 1 row affected, 3 warnings (0.03 sec)

mysql> select * from tb_1;
+----+------+--------+----------+---------+-------+
| id | name | gender | company  | salary  | fanbu |
+----+------+--------+----------+---------+-------+
|  6 |      |        |          |  999.00 |    11 |
|  2 | 李四     | 女      | 騰訊        | 6524.50 |  1000 |
|  3 | 王五     | 男       | 新浪         | 5000.00 |   520 |
|  4 | 趙六     | 女      | 阿里巴巴        | 5600.00 |   300 |
|  5 | 劉思    | 女      | 支付寶        | 3000.00 |   200 |
+----+------+--------+----------+---------+-------+
5 rows in set (0.00 sec)

mysql> set character_set_client=gbk;
Query OK, 0 rows affected (0.00 sec)

mysql> select * from tb_1;
+----+------+--------+----------+---------+-------+
| id | name | gender | company  | salary  | fanbu |
+----+------+--------+----------+---------+-------+
|  6 |      |        |          |  999.00 |    11 |
|  2 | 李四     | 女      | 騰訊        | 6524.50 |  1000 |
|  3 | 王五     | 男       | 新浪         | 5000.00 |   520 |
|  4 | 趙六     | 女      | 阿里巴巴        | 5600.00 |   300 |
|  5 | 劉思    | 女      | 支付寶        | 3000.00 |   200 |
+----+------+--------+----------+---------+-------+
5 rows in set (0.00 sec)

  

  能夠看到,字節丟失了,咱們輸入的信息不見了,怎麼理解?

    GBK漢字mysql以utf8存了,可是咱們已經設置顯示結果是GBK,按理來講,utf8的亂碼,翻譯過來仍是GBK的正確啊?

  就像這樣:

         假如:王 二進制GBK:0001 –> 存儲UTF8 0010

                   取出時:UTF8 0010 -> GBK 0001

         不該該不對啊?

         實際上是這樣的:

         假如:王 二進制GBK:0001 –> character_set_client沒有設置,mysql覺得這個0001是UTF8的因此這裏存儲UTF8 0001 而0001的UTF8對應是個:李,

                   取出時:UTF8 0001(李) -> character_set_results=GBK –>將UTF8的 0001轉爲了GBK的0110了,此時GBK也不知道這是個什麼東西了,GBK沒有這個字符,因此沒法顯示

  注意

 

    可是很不幸,mysql自帶的客戶端,這些set names gbk;等命令的設置都只是臨時的!!

 

    當咱們,關閉client,從新打開時,咱們會發現又亂了,又要從新設置,哎!因此每次使用必定首先設置好這個東西,對於怎樣不用這麼麻煩?我沒有深刻的去研究,可是當你肯定你不少時候用的是GBK編碼或者其餘編碼時,那麼就在安裝mysql時注意設置

  好了,就這麼多吧,這些筆記,不光只是抄寫,也是加入了一些之前本身的認識和驗證的猜測,總的感受就是:此次算是基本弄明白了,這些編碼是怎麼一回事了。

  若是有什麼錯誤和不明白的地方,親你們留言,謝謝!睡覺嘍,吼吼、、、、、

相關文章
相關標籤/搜索