最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

MySQL字符集中文亂碼解析

 更新時(shí)間:2023年09月12日 09:20:38   作者:張松坡坡坡坡  
這篇文章主要給大家解析了MySQL字符集中文亂碼的問(wèn)題,文章通過(guò)代碼示例講解的非常詳細(xì),對(duì)我們的學(xué)習(xí)或工作有一定的幫助,需要的朋友可以參考下

問(wèn)題描述

假設(shè)有三個(gè)表test_gbk,test_utf8,test_latin1,創(chuàng)建的時(shí)候字符集分別為gbk,utf8,latin1。表結(jié)構(gòu)為

FieldTypeNullKeyDefaultExtra
namevarchar(512)YESNULL

"中"字的gbk十六進(jìn)制表示為:0xd6 d0;utf8 16進(jìn)制表示為:0xe4 b8 ad

問(wèn)題1

執(zhí)行下列語(yǔ)句:

set names 'latin1'; 
insert into test_latin1 values( '中');   //此處'中'為gbk格式
select name from test_latin1;

結(jié)果是亂碼,還是正常顯示?

問(wèn)題2

執(zhí)行下列語(yǔ)句:

set names 'gbk'; 
insert into test_latin1 values( '中');  //此處'中'為gbk格式
select name from test_latin1;

結(jié)果是亂碼,還是正常顯示?

問(wèn)題3

執(zhí)行下列語(yǔ)句:

set names 'latin1'; 
insert into test_utf8 values( '中');  //此處'中'為gbk格式
select name from test_utf8;

結(jié)果是亂碼,還是正常顯示?

原理篇

字符集介紹

為了解釋上述問(wèn)題,首先要了解字符集為何物。字符集也叫字符編碼,就是將字符集合一一映射成一個(gè)數(shù)。以下簡(jiǎn)單介紹一下幾種字符集:

基礎(chǔ)ASCII編碼:

0x00-0x7F表示所有的大寫(xiě)和小寫(xiě)字母,數(shù)字0 到9、標(biāo)點(diǎn)符號(hào), 以及在美式英語(yǔ)中使用的特殊控制字符。

latin1編碼:

單字節(jié)編碼,編碼范圍是0x00-0xFF,0x00-0x7F,和ASCII保持一致,0x80-0x9F之間是控制字符,0xA0-0xFF之間是文字符號(hào)。

gbk編碼:

使用一字節(jié)和雙字節(jié)編碼,0x00–0x7F范圍內(nèi)是一位,和ASCII保持一致。雙字節(jié)的第一字節(jié)范圍是0x81-0xFE(不含0x800xFF)。

utf8編碼:

使用一至四字節(jié)編碼,0x00–0x7F范圍內(nèi)是一位,和ASCII保持一致。其它字符用二至四個(gè)字節(jié)變長(zhǎng)表示。

字符集編碼轉(zhuǎn)換舉例:

0xB1(latin-1) ->'±'-> 0xC2 B1 (utf8)

兩個(gè)重要的點(diǎn)

  • 0x00-0x7F區(qū)間,上述字符集是一致的,也就是說(shuō)英文字符無(wú)需轉(zhuǎn)碼。

  • 不同編碼,字符集合不完全一樣,存在某字符集的字符無(wú)法映射到另外一個(gè)字符集。

比如gbk編碼中的中文字符,轉(zhuǎn)成latin-1編碼時(shí),就找不到對(duì)應(yīng)的二進(jìn)制編碼。MySQL做字符集轉(zhuǎn)換的時(shí)候,gbk中文字符->latin-1,很多就轉(zhuǎn)成'?'號(hào)(0x3f),這種大集合轉(zhuǎn)成小集合,基本是不可逆的。

MySQL執(zhí)行過(guò)程

對(duì)一個(gè)MySQL的執(zhí)行過(guò)程,字符集轉(zhuǎn)換,一般涉及到一下三個(gè)步驟:

  • 收到請(qǐng)求,將請(qǐng)求數(shù)據(jù)從 character_set_client ->character_set_connection。

  • 內(nèi)部操作,將數(shù)據(jù)從character_set_connection-> 表創(chuàng)建的字符集。

  • 結(jié)果輸出,將數(shù)據(jù)從表創(chuàng)建的字符集 -> character_set_results

當(dāng)執(zhí)行set names "charset"; 相當(dāng)于把character_set_client, character_set_connection,character_set_results 統(tǒng)一設(shè)置為"charset"。

終端顯示字符集

此外如果你用securecrt終端來(lái)顯示的話,如果不想亂碼的話,appearance->character encoding也需要設(shè)置成正確的字符集。

問(wèn)題詳解

問(wèn)題1

執(zhí)行下列語(yǔ)句:

set names 'latin1'; 
insert into test_latin1 values( '中');   //此處'中'為gbk格式
select name from test_latin1;

結(jié)果是亂碼,還是正常顯示?

答:結(jié)果是正常顯示。

執(zhí)行流程如下:

  • set names 'latin1';相當(dāng)于把character_set_client, character_set_connection,character_set_results 統(tǒng)一設(shè)置為'latin1'。

  • Character_set_client告訴MySQL Server,傳入的是一個(gè)latin1編碼的,也就是單字節(jié)流,'中'這個(gè)輸入,其實(shí)當(dāng)作了0xD6 D0傳入。

  • 因?yàn)?code>character_set_client -> character_set_connection-> table charset -> character_set_resultslatin1 ->latin1 -> latin1 -> latin1, 編碼完全一致,數(shù)據(jù)沒(méi)有做任何轉(zhuǎn)換,所以輸入是0xD6 D0,最后的輸出也還原為0xD6 D0。

  • 如果你的securecrt的顯示字符集設(shè)置為gbk,那么最后的輸出0xD6 D0就會(huì)顯示成'中'。

問(wèn)題2

執(zhí)行下列語(yǔ)句:

set names 'gbk'; 
insert into test_latin1 values( '中');  //此處'中'為gbk格式
select name from test_latin1;

結(jié)果是亂碼,還是正常顯示?

答:結(jié)果是亂碼。

執(zhí)行流程如下:

  • set names 'gbk';相當(dāng)于把character_set_client, character_set_connection,character_set_results統(tǒng)一設(shè)置為'gbk'。

  • Character_set_client告訴MySQL Server,傳入的是一個(gè)gbk編碼的,'中'這個(gè)輸入,當(dāng)作了0xD6 D0傳入。

  • 因?yàn)?code>character_set_client -> character_set_connection -> table charset-> character_set_resultsgbk-> gbk-> latin1 -> gbk, 其中gbk-> latin1的時(shí)候,因?yàn)?#39;中'這個(gè)字符在latin1字符集里找不到,就會(huì)轉(zhuǎn)換成'?'號(hào)(0x3F),然后latin1->gbk,'?'號(hào)在gbk字符集里面也是0x3F,最后輸出就是0x3F,即'?'號(hào)。

問(wèn)題3

執(zhí)行下列語(yǔ)句:

set names 'latin1'; 
insert into test_utf8 values( '中');  //此處'中'為gbk格式
select name from test_utf8;

結(jié)果是亂碼,還是正常顯示?

答:正常顯示。

執(zhí)行流程如下:

  • set names 'latin1';相當(dāng)于把character_set_client, character_set_connection,character_set_results 統(tǒng)一設(shè)置為'latin1'。

  • Character_set_client告訴MySQL Server,傳入的是一個(gè)latin1編碼的,'中'這個(gè)輸入,當(dāng)作了0xD6 D0傳入。

  • 因?yàn)?code>character_set_client -> character_set_connection -> table charset -> character_set_resultslatin1-> latin1-> utf8 -> latin1, 其中latin1-> utf8的時(shí)候,輸入'中' (0xD6 D0)會(huì)當(dāng)作兩個(gè)字符進(jìn)行utf8轉(zhuǎn)換,轉(zhuǎn)換為0xC3 96 C3 90,然后utf8->latin1的時(shí)候,會(huì)把0xC3 96轉(zhuǎn)換成0xD6, 0xC3 90轉(zhuǎn)成0x D0,最后輸出0xD6 D0。負(fù)負(fù)得正,之所以數(shù)據(jù)沒(méi)有失真的原因是因?yàn)樾〖贤蠹限D(zhuǎn),再轉(zhuǎn)回來(lái),操作可逆。

  • 如果你的securecrt的顯示字符集設(shè)置為gbk,那么最后的輸出0xD6 D0就會(huì)顯示成'中'。

終極解決方案

從上面的問(wèn)題執(zhí)行流程來(lái)看,有沒(méi)有終極解決方案呢?其實(shí)很簡(jiǎn)單,表創(chuàng)建的字符集和set names都設(shè)置成同一個(gè)字符集,就基本可以滿足輸入數(shù)據(jù)不會(huì)在轉(zhuǎn)換過(guò)程中失真,也就是說(shuō)輸入是什么,輸出就是什么。建議有中文的都設(shè)置成utf8字符集,一勞永逸。

以上就是MySQL字符集中文亂碼解析的詳細(xì)內(nèi)容,更多關(guān)于MySQL字符集中文亂碼的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • MySQL 最基本的SQL語(yǔ)法/語(yǔ)句

    MySQL 最基本的SQL語(yǔ)法/語(yǔ)句

    MySQL 最基本的SQL語(yǔ)法/語(yǔ)句,使用mysql的朋友可以參考下。
    2011-09-09
  • mysql數(shù)據(jù)庫(kù)安裝和卸載方式

    mysql數(shù)據(jù)庫(kù)安裝和卸載方式

    這篇文章主要介紹了mysql數(shù)據(jù)庫(kù)安裝和卸載方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2024-06-06
  • MySQL 選擇合適的存儲(chǔ)引擎

    MySQL 選擇合適的存儲(chǔ)引擎

    這篇文章主要介紹了MySQL如何選擇合適的存儲(chǔ)引擎,幫助大家更好的理解和使用MySQL數(shù)據(jù)庫(kù),感興趣的朋友可以了解下
    2020-09-09
  • MySQL 8.0 Online DDL快速加列的相關(guān)總結(jié)

    MySQL 8.0 Online DDL快速加列的相關(guān)總結(jié)

    在實(shí)際的MySQL運(yùn)維過(guò)程中,我們經(jīng)常會(huì)遇到業(yè)務(wù)需要給某張表添加字段的情況,本文將介紹幾種加字段的方法,感興趣的朋友可以參考下
    2021-06-06
  • mysql中關(guān)于between和in的區(qū)別

    mysql中關(guān)于between和in的區(qū)別

    這篇文章主要介紹了mysql中關(guān)于between和in的區(qū)別說(shuō)明,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-07-07
  • MySQL9.0.1安裝教程的實(shí)現(xiàn)示例

    MySQL9.0.1安裝教程的實(shí)現(xiàn)示例

    本文主要介紹了MySQL軟件的下載、解壓、環(huán)境變量配置、初始化及啟動(dòng)、登錄與密碼設(shè)置等步驟,詳細(xì)說(shuō)明了每一步的操作方法,感興趣的可以了解一下
    2024-10-10
  • Windows系統(tǒng)下MySQL ODBC驅(qū)動(dòng)安裝與配置詳細(xì)步驟

    Windows系統(tǒng)下MySQL ODBC驅(qū)動(dòng)安裝與配置詳細(xì)步驟

    本文介紹Windows系統(tǒng)下MySQL ODBC驅(qū)動(dòng)的安裝與配置步驟,涵蓋系統(tǒng)架構(gòu)確認(rèn)、驅(qū)動(dòng)下載選擇、DSN配置、ANSI/Unicode驅(qū)動(dòng)區(qū)別及常見(jiàn)問(wèn)題解決方案,同時(shí)提供自動(dòng)化部署腳本,幫助用戶解決驅(qū)動(dòng)未顯示、位數(shù)沖突、連接失敗等典型問(wèn)題,感興趣的朋友一起看看吧
    2025-06-06
  • MySQL中CURRENT_TIMESTAMP的使用方式

    MySQL中CURRENT_TIMESTAMP的使用方式

    這篇文章主要介紹了MySQL中CURRENT_TIMESTAMP的使用方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-11-11
  • MySQL中大數(shù)據(jù)表增加字段的實(shí)現(xiàn)思路

    MySQL中大數(shù)據(jù)表增加字段的實(shí)現(xiàn)思路

    最近遇到的一個(gè)問(wèn)題,需要在一張將近1000萬(wàn)數(shù)據(jù)量的表中添加加一個(gè)字段,但是直接添加會(huì)導(dǎo)致mysql 奔潰,所以需要利用其他的方法進(jìn)行添加,這篇文章主要給大家介紹了MySQL中大數(shù)據(jù)表增加字段的實(shí)現(xiàn)思路,需要的朋友可以參考借鑒。
    2017-01-01
  • MySQL9.0默認(rèn)路徑安裝下重置root密碼

    MySQL9.0默認(rèn)路徑安裝下重置root密碼

    本文主要介紹了MySQL9.0默認(rèn)路徑安裝下重置root密碼,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2025-02-02

最新評(píng)論

桂东县| 高台县| 靖西县| 工布江达县| 威远县| 宝坻区| 崇阳县| 黑河市| 曲松县| 梅河口市| 龙山县| 台中市| 宁海县| 曲水县| 邯郸市| 赞皇县| 商都县| 阿坝| 东光县| 马公市| 巴林左旗| 绥化市| 宁夏| 嘉禾县| 黑水县| 长汀县| 都安| 县级市| 唐河县| 金寨县| 临桂县| 明水县| 富源县| 肃宁县| 惠安县| 五寨县| 儋州市| 香港 | 八宿县| 德清县| 古丈县|