接着上一篇繼續來一篇關於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時注意設置
好了,就這麼多吧,這些筆記,不光只是抄寫,也是加入了一些之前本身的認識和驗證的猜測,總的感受就是:此次算是基本弄明白了,這些編碼是怎麼一回事了。
若是有什麼錯誤和不明白的地方,親你們留言,謝謝!睡覺嘍,吼吼、、、、、