亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 數據庫 > MySQL > 正文

MySQL亂碼問題終極指南

2024-07-24 13:09:13
字體:
來源:轉載
供稿:網友
為了讓大家盡量在工作中少受或者不受亂碼的困擾,這篇文章主要為大家分享了MySQL亂碼問題終極指南,感興趣的小伙伴們可以參考一下
 

mysql的字符集設置眾多,從客戶端到連接到結果集,從服務器到庫到表到列,都可以設置字符集,靈活很強大,但就是很容易出問題,如果不了解其機制,很容易就出現亂碼問題。

為了讓大家盡量在工作中少受或者不受亂碼的困擾,這里我結合之前其它同學在論壇的發帖,并結合自己的理解和實踐,詳細分析總結了一下,以饗各位看官。

關于字符集和亂碼的基礎知識這里就不詳細說明了(請自行搜索),但有一個問題需要特別強調一下:亂碼是怎么產生的?
這個問題相信很多同學都是模棱兩可,或者沒有認真想過,反正理解就是”字符編碼“不對導致亂碼,但沒有真正想過為什么”字符編碼“會導致亂碼。
答案其實很簡單:“轉換導致亂碼”!
根據這個原則來判斷,各種情況就很簡單了:

1)數據傳送過程中不會導致亂碼
2)數據存儲不會導致亂碼
3)數據輸入和輸出(包括顯示)可能導致亂碼
4)數據接收和發送可能導致亂碼

更詳細的解釋:轉換導致亂碼是指本來是A字符集的數據被當成了B字符集進行解析,而不是說正確的A字符集轉換為B字符集。
例如:如下mysql字符處理機制流程圖中,mysql客戶端發送的實際上是2個gbk字符(4字節),但character_set_connection
設置了utf8,于是mysql服務器將收到的4字節gbk數據按照utf8解析,得到1個中文字符+1個字節,這時就產生亂碼了;

如果character_set_connection 設置為gbk,mysql服務器收到數據后按照gbk解析,得到兩個正確的中文,然后再轉換為這兩個中文對應的utf8編碼,這就不會產生亂碼。)

【mysql的字符處理機制】

詳細的處理機制如下圖:

MySQL,亂碼
 

我們模擬一下一條數據從插入到讀取的處理流程,看看在整個流程中,字符集是如何輾轉騰挪的。
【插入流程】
1. 客戶端設定了自己的編碼(character_set_client),接收用戶的輸入;
2. 客戶端將用戶的輸入“轉換”成連接的編碼(character_set_connection) =====> 第一次轉換
3. 客戶端將轉換后的數據發送給服務器;                               =====> 傳輸不會導致編碼轉換
4. 服務器收到客戶端的數據,再判斷數據列的字符集,進行字符轉換       =====> 第二次轉換
5. 服務器將數據存儲(例如磁盤)                                     =====> 存儲不會導致編碼轉換  

【讀取流程】
略去前面的sql語句處理流程,從數據讀取開始
1. 服務器從存儲(例如磁盤)讀取數據                                 =====> 存儲不會導致編碼轉換,因此從存儲讀取也不需要
2. 服務器判斷當前連接返回結果的字符集(character_set_results),
   將讀取的數據轉換為結果集要求的數據                               =====> 逆向的第一次轉換,對應正向的第二次編碼轉換
3. 服務器將數據發送給客戶端                                         =====> 傳輸不會導致編碼轉換
4. 客戶端收到服務器的數據,根據客戶端的字符集(character_set_client)進行編碼轉換          =====> 逆向第二次轉換,對應正向第一次編碼轉換
5. 客戶端顯示數據                                                   =====> 你能看到亂碼的時候

有了這個流程,我們就很容易定位亂碼可能產生的地方,以及產生亂碼的字符集配置究竟是哪個了。
理想的情況是整個流程中,所有涉及字符轉換的地方都不需要轉換,這樣就不會產生亂碼了。

有了上面的理論分析后,我們再結合一個亂碼的抓包實例,加深理解,其中有一些問題,請大家思考一下,看看是否真的理解了。

環境:
+--------------------------+-----------------------------------------------------+
| Variable_name            | Value                                               |
+--------------------------+-----------------------------------------------------+
| character_set_client     | latin1                                              |
| character_set_connection | latin1                                              |
| character_set_database   | utf8                                                |
| character_set_filesystem | binary                                              |
| character_set_results    | latin1                                              |
| character_set_server     | utf8                                                |

測試語句是插入一個中文字符“你”,其utf8編碼為"0xE4 0xBD 0xA0",

1. latin1發送包 

MySQL,亂碼

思考一下1:為什么客戶端和連接都設置了latin1,但最終發送的是正確的utf8編碼呢?

2. latin1接收包 

MySQL,亂碼

思考一下2:為什么接收到的還是正確的utf8編碼?

3. latin1不顯示亂碼 

MySQL,亂碼

思考一下3:為什么latin1顯示了正確的utf8字符?

4. utf8接收包 

MySQL,亂碼

思考一下4:為什么連接的字符集和數據庫的字符集設置成一樣了,接收的數據反而不是utf8了?(請與latin1接收數據包對比)

5. utf8顯示包

MySQL,亂碼

思考一下5:為什么連接的字符集和數據庫的字符集設置成一樣了,顯示反而亂碼了? 

怎么樣,上面的思考題是否都有答案了,如果沒有,相信下面這幅圖能夠幫助你:

這個抓包案例的字符變化圖解:

MySQL,亂碼

附:mysql字符編碼操作技巧
【查看字符集設置】

mysql> show variables like '%char%';+--------------------------+-----------------------------------------------------+| Variable_name      | 說明                        |+--------------------------+-----------------------------------------------------+| character_set_client   | 客戶端字符集                    || character_set_connection | 當前連接字符集                   || character_set_database  | 數據庫字符集                    || character_set_filesystem | 文件系統字符集,不要修改,使用binary即可      || character_set_results  | 返回結果集字符集                  || character_set_server   | 服務器默認字符集,當數據庫、表、列沒有設置時,   ||             |   默認使用此字符集                || character_set_system   | 固定為utf8                     |+--------------------------+-----------------------------------------------------+ 

【修改字符集設置】
服務器的配置在服務器建立的時候就由DBA設置好了,不推薦后續再改
通過SET NAMES utf8命令同時設置character_set_client/character_set_connection/character_set_results的字符集
建議所有配置都設置成utf8

【問題答案】

思考一下1:為什么客戶端和連接都設置了latin1,但最終發送的是正確的utf8編碼呢?
客戶端設置了latin1,而我的語句是從notepad++中寫好的,是utf8格式的;
中文utf8是3個字節,而latin1是按照單個字節解析的,雖然進行了轉換,但不會導致二進制內容的變化,但實際上mysql客戶端認為我輸入了3個latin1字符;
如果客戶端設置的編碼是2個字節的gbk,這時轉換就會發生亂碼,utf8的3個字節會被轉換為1個gbk字符(可能是亂碼,也可能不是亂碼)加上一個西歐字符(小于128就是英文,大于128就是其它西歐文)

思考一下2:為什么接收到的還是正確的utf8編碼?
這是因為mysql服務器從將數據從“列”的編碼(utf8)轉換為latin1了,而列存儲的數據并不是真正的utf8的中文“你”對應的"0xe4 0xbd 0xa0",
而是后面抓包看到的“c3a4 c2bd c2a0”(6個字節),mysql服務器將utf8的c3a4轉換為latin1的0xe4,c2bd轉換為0xbd, c2a0轉換為0xa0

思考一下3:為什么latin1顯示了正確的utf8字符?
因為mysql客戶端收到了mysql服務器轉換后的"0xe4 0xbd 0xa0",并把這個數據當做latin1的3個字符處理,然后拋給終端(我的是SecureCRT),
SecureCRT又把這三個latin1當做uft8處理,結果中文的“你”就顯示出來了。

思考一下4:為什么連接的字符集和數據庫的字符集設置成一樣了,接收的數據反而不是utf8了?(請與latin1接收數據包對比)
字符集都一樣的情況下,整個流程中不需要進行編碼轉換,直接將存儲的“c3a4 c2bd c2a0”返回給客戶端

思考一下5:為什么連接的字符集和數據庫的字符集設置成一樣了,顯示反而亂碼了?
參考思考4,客戶端收到數據后也直接拋給終端顯示,終端認為是兩個utf8字符,并且找到了對應字符并顯示,但我們看不懂,所以知道是亂碼了,但這兩個字符顯示并沒有錯,如果真正找不到字符,可能會顯示問號或者字符集規定的缺省符號。

以上就是關于MySQL亂碼問題大集合,希望能夠幫助大家解決MySQL亂碼問題,謝謝大家的閱讀。



注:相關教程知識閱讀請移步到MYSQL教程頻道。
發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
国产99久久久欧美黑人| 亚洲香蕉在线观看| 日韩高清av一区二区三区| 久久天天躁狠狠躁夜夜躁| 欧美午夜激情视频| 91久久在线观看| 俺去亚洲欧洲欧美日韩| 欧美精品国产精品日韩精品| 久久久久久国产三级电影| 91免费看片网站| 精品无人国产偷自产在线| 欧美亚洲国产视频小说| 久久天天躁夜夜躁狠狠躁2022| 国产精品爽爽爽爽爽爽在线观看| 色婷婷综合久久久久中文字幕1| 色香阁99久久精品久久久| 日本成熟性欧美| 久久久999精品| 在线精品播放av| 亚洲欧美激情精品一区二区| 欲色天天网综合久久| 在线亚洲国产精品网| 北条麻妃99精品青青久久| 岛国精品视频在线播放| 国产精品999999| 欧美午夜精品伦理| 国产专区精品视频| 国产精品视频最多的网站| 亚洲va久久久噜噜噜| 一区二区三区回区在观看免费视频| 色综合久久精品亚洲国产| 国内外成人免费激情在线视频网站| 国产精品27p| 91国产精品91| 日韩美女写真福利在线观看| 欧美洲成人男女午夜视频| 国产精品久久久久久久久久久久久| 亚洲bt天天射| 欧美性高潮在线| 国产va免费精品高清在线观看| 久久久久久久久综合| 亚洲欧美国内爽妇网| 日韩成人高清在线| 欧美中文字幕在线| 日韩视频在线免费| 97国产一区二区精品久久呦| 亚洲国产精品电影| 色小说视频一区| 91av在线精品| 久久久久五月天| 久久成人人人人精品欧| 欧美日韩国产va另类| 欧美视频专区一二在线观看| 欧洲日韩成人av| xxav国产精品美女主播| 亚洲欧洲xxxx| 午夜精品久久久久久久99热浪潮| 国产视频福利一区| 国产精品久久久久久久久久小说| 91亚洲午夜在线| 91麻豆国产语对白在线观看| 欧美日韩午夜视频在线观看| 亚洲成在人线av| 国产精品99久久久久久www| 亚洲自拍偷拍区| 亚洲精品免费网站| 欧美激情精品久久久久| 国产精品中文字幕在线观看| 97国产在线观看| 在线观看日韩www视频免费| 国产欧美日韩视频| 欧美电影院免费观看| 亚洲国产成人精品一区二区| 日本国产欧美一区二区三区| 国产欧美日韩专区发布| 日韩中文字幕精品| 亚洲天堂影视av| 91亚洲国产精品| 国内精品久久久久久久久| 国产91精品青草社区| 日韩av一区二区在线| 国产一区二中文字幕在线看| 亚洲最大激情中文字幕| 欧美日韩福利视频| 国产亚洲欧美日韩一区二区| 欧美日韩激情视频| 中文字幕日韩欧美精品在线观看| 7777kkkk成人观看| 欧美日韩人人澡狠狠躁视频| 国产伦精品免费视频| 在线播放日韩欧美| 全色精品综合影院| 91极品视频在线| 91在线播放国产| 日韩av综合网站| 色婷婷综合久久久久| 日韩精品免费观看| 日韩免费黄色av| 在线观看日韩欧美| 亚洲人成在线播放| 国产欧美va欧美va香蕉在| 国产精品视频地址| 欧美日韩国产中字| 26uuu亚洲伊人春色| 亚洲图片在区色| 久久亚洲春色中文字幕| 日本不卡高字幕在线2019| 亚洲美女性视频| 亚洲国产日韩欧美在线动漫| 亚洲人精选亚洲人成在线| 日韩在线视频一区| 亚洲人成电影在线观看天堂色| 日韩欧美中文字幕在线播放| 青草青草久热精品视频在线观看| 国产精品草莓在线免费观看| 国产亚洲视频在线观看| 成人午夜激情免费视频| 欧美日韩在线观看视频小说| 久久综合免费视频| 欧美午夜精品久久久久久浪潮| 国产精品亚洲第一区| 97视频网站入口| 国产精品www网站| 欧美激情视频三区| 亚洲一区二区国产| 精品视频在线播放免| 久久久精品久久久| 国产精品视频26uuu| 亚洲国产91色在线| 欧美电影在线免费观看网站| 97视频免费在线观看| 性欧美暴力猛交69hd| 欧美激情一区二区三级高清视频| 国产综合在线观看视频| 国产精品美女主播在线观看纯欲| 欧美福利视频网站| 久久久国产精品视频| 成人高h视频在线| 国产亚洲欧美另类中文| 亚洲国产97在线精品一区| 91国产精品91| 国产大片精品免费永久看nba| 欧美成人免费在线观看| xxx欧美精品| 久久久这里只有精品视频| 日本久久久久久久| 久久久中文字幕| 91久久久久久久久久久久久| 欧美激情精品久久久久久| 久久九九精品99国产精品| 亚洲精品av在线| 欧美视频在线观看免费网址| 精品国产一区二区三区在线观看| 久久视频精品在线| 亚洲精品国产精品乱码不99按摩| 欧美日韩在线免费观看| 久久久久久久久久久亚洲| 美女久久久久久久| 亚洲黄色av网站| 国产91在线播放| 欧美另类暴力丝袜| 日韩在线中文字| 久久这里只有精品视频首页| 日韩免费在线电影|