您好,登錄后才能下訂單哦!
這期內(nèi)容當(dāng)中小編將會(huì)給大家?guī)?lái)有關(guān)如何進(jìn)行mysql亂碼產(chǎn)生的探討,文章內(nèi)容豐富且以專(zhuān)業(yè)的角度為大家分析和敘述,閱讀完這篇文章希望大家可以有所收獲。
實(shí)驗(yàn)一
1。首先,在下面情況下:
mysql> show variables like 'character_set_%';
+--------------------------+---------------------------------------+
| Variable_name | Value |
+--------------------------+---------------------------------------+
| character_set_client | latin1 |
| character_set_connection | latin1 |
| character_set_database | latin1 |
| character_set_filesystem | binary |
| character_set_results | latin1 |
| character_set_server | latin1 |
| character_set_system | utf8 |
| character_sets_dir | D:\Programs\mysql5045\share\charsets\ |
+--------------------------+---------------------------------------+
建表,并加入3個(gè)記錄:大,阿,愛(ài)
2。set character_set_results=utf8;
則顯示:(cmd窗口中,cmd窗口代碼頁(yè)936)
大->麓貿(mào)
阿->擄壟
愛(ài)->擄廬
分析編碼:
大U:5927,GBK:B4F3
麓U:9E93,GBK:C2B4
貿(mào)U:8D38,GBK:C3B3
阿U:963F,GBK:B0A2
擄U:63B3,GBK:C2B0
壟U:5784,GBK:C2A2
愛(ài)U:7231,GBK:B0AE
擄U:63B3,GBK:C2B0
廬U:5E90,GBK:C2AE
3。改成set character_set_results=gb2312;
一樣是亂碼
4。結(jié)論:
亂碼的產(chǎn)生,是由于單字節(jié)向多字節(jié)擴(kuò)展引起的。B0A2 如果作為單字節(jié)存儲(chǔ)(雖然表示的是1個(gè)漢字,但是因?yàn)槭莑atin1單字節(jié),所以認(rèn)為B0A2是不相關(guān)的兩個(gè)字符),此時(shí)如果把character_set_results變成utf8多字節(jié),那么數(shù)據(jù)庫(kù)mysql 會(huì)試圖把每個(gè)單字節(jié)擴(kuò)展成近似的(不知道具體的算法)雙字節(jié)。所以亂碼
反之,多字節(jié)向單字節(jié)轉(zhuǎn)換時(shí),不會(huì)有變動(dòng),僅僅是原來(lái)2各字節(jié)表示的一個(gè)字符‘B0A2’變成了表示兩個(gè)字符而已。---- 這個(gè)說(shuō)法經(jīng)驗(yàn)證是錯(cuò)誤的。
數(shù)據(jù)庫(kù)存儲(chǔ)的內(nèi)容(磁盤(pán)上,內(nèi)存里)不會(huì)受character_set_的影響,只是提交,查詢(xún)的過(guò)程中,受到字符集轉(zhuǎn)換的影響。
實(shí)驗(yàn)二
1。
create table y (id int, name char(4)) default charset gb2312;
2。在不改變默認(rèn)character_set_ 是latin1的情況下,如果插入一個(gè)漢字,則顯示亂碼
3。改成set names gb2312,顯示沒(méi)問(wèn)題(cmd窗口中,cmd窗口代碼頁(yè)936)
4。我原以為如上述實(shí)驗(yàn)1種的結(jié)論2,“多字節(jié)向單字節(jié)轉(zhuǎn)換時(shí),不會(huì)有變動(dòng)”。所以我開(kāi)始以為,set names gb2312 后,把character_set_results 改成latin1,顯示不會(huì)出問(wèn)題。結(jié)果,
一個(gè)漢字,則顯示一個(gè)問(wèn)號(hào);兩個(gè)漢字,則顯示兩個(gè)問(wèn)號(hào)的亂碼(估計(jì)一個(gè)問(wèn)號(hào)代表一個(gè)字符)。也就是說(shuō),改成character_set_results = latin1后,多字節(jié)的數(shù)據(jù)存儲(chǔ),在向單字節(jié)表示轉(zhuǎn)換時(shí),mysql把提出的信息“縮水了”,把兩個(gè)字節(jié),換算成了一個(gè)字節(jié)。
5。如何,不讓mysql縮水呢,我想到了character_set_results = binary;結(jié)果,果然顯示正常。
PS
開(kāi)發(fā)的使用mysql的應(yīng)用程序,是對(duì)應(yīng)作為獨(dú)立的使用自己的character_set_client的字符集的
cmd 窗口登陸mysql,也是作為一個(gè)獨(dú)立的,擁有自己character_set_client變量的應(yīng)用
同理,打開(kāi)不同的cmd窗口,都擁有獨(dú)自的character_set_client變量
實(shí)驗(yàn)三07/16/2010
1。建一個(gè)默認(rèn)字符集utf8的表(用navicat ,在utf8的界面下 代碼頁(yè)65001),并且插入utf8編碼的漢字;大學(xué);
2。切換到mysql console(代碼頁(yè)936)
3。set names gbk; 然后顯示剛才所建立的表,能正確現(xiàn)實(shí)嗎?---- 能!當(dāng)然,只把character_set_results 成gbk,也能正常顯示
實(shí)驗(yàn)四
1。mysql console(代碼頁(yè)936)建立一個(gè)表x3 ( name char(32) ),默認(rèn)字符集default charset gbk;
2。默認(rèn)環(huán)境變量
| character_set_client | latin1
| character_set_connection | latin1
| character_set_database | latin1
| character_set_filesystem | binary
| character_set_results | latin1
| character_set_server | latin1
| character_set_system |utf8 //不知道對(duì)以下過(guò)程、分析是否有影響
character_set_client character_set_connection character_set_results 是latin1的情況下,插入數(shù)據(jù):insert x3 values('大');
顯示:ERROR 1406 (22001): Data too long for column 'name' at row 1
3。set character_set_client=gbk;然后insert x3 values('大');插入沒(méi)有問(wèn)題,但顯然,數(shù)據(jù)經(jīng)過(guò) (character_set_connection=latin1)的轉(zhuǎn)換,已經(jīng)是有損了
4。不管character_set_results 設(shè)不設(shè)成gbk,都不能正常顯示結(jié)果
5。set names gbk;則插入現(xiàn)實(shí)都沒(méi)問(wèn)題。并且此時(shí),一個(gè)uf8字符集的表的顯示也沒(méi)問(wèn)題(實(shí)驗(yàn)三)。而且進(jìn)行連接查詢(xún),亦沒(méi)問(wèn)題。
6。當(dāng)然,set names utf8,如果在一個(gè)utf8的軟件界面上,顯示輸出也沒(méi)問(wèn)題(navicat 驗(yàn)證了)
7。如果設(shè)成set names binary。在936代碼頁(yè)的顯示界面上,可以看到,x3依然可以正常現(xiàn)實(shí);但像實(shí)驗(yàn)三那樣建的表就不能正常顯示了。
--------
分析第2點(diǎn):Data too long for column 'name' at row 1
我的char 夠長(zhǎng),插入數(shù)據(jù)夠短,所以不是數(shù)據(jù)太長(zhǎng)了。也就是說(shuō)這個(gè)提示是錯(cuò)誤的。
我知道,如果表x3 默認(rèn)字符集 是latin1的話,插入是沒(méi)問(wèn)題的(一直以來(lái)都是這么玩的);這是因?yàn)椋m然輸入端mysql console 代碼頁(yè)是936,但因?yàn)槿齻€(gè)主環(huán)境變量character_set_c%都是latin1,所以,mysql 認(rèn)為insert x3 values('大') 輸入的是2個(gè)字符(當(dāng)然,如果從utf8界面輸入,可能就認(rèn)為是輸入3個(gè)字符)。存儲(chǔ)的自然也是2個(gè)字符。顯示的時(shí)候也是顯示的2個(gè)字符,只不過(guò)936代碼頁(yè)把這兩個(gè)字符自然組合,顯示成漢字了(早期環(huán)境常見(jiàn)現(xiàn)象)。
當(dāng)默認(rèn)字符集變?yōu)間bk的時(shí)候,發(fā)生了什么?不知道。。。。。
實(shí)驗(yàn)五
一個(gè)很狗屎的問(wèn)題出現(xiàn)了:936 console
環(huán)境變量如 實(shí)驗(yàn)一.1。
mysql> set names latin1;
Query OK, 0 rows affected (0.00 sec)
mysql> create table x4 (
-> name char(32) primary key);
Query OK, 0 rows affected (0.09 sec)
mysql> drop table x4;
Query OK, 0 rows affected (0.06 sec)
mysql> create table x4 (
-> name char(32) primary key) default charset utf8;
Query OK, 0 rows affected (0.10 sec)
mysql> insert x4 values('乃');
Query OK, 1 row affected (0.04 sec)
mysql> create table x5 (
-> name char(32) primary key) default charset gbk;
Query OK, 0 rows affected (0.09 sec)
mysql> insert x5 values('乃');
ERROR 1406 (22001): Data too long for column 'name' at row 1
mysql>
結(jié)論,我實(shí)在對(duì)實(shí)驗(yàn)四中分析的第3點(diǎn)做出結(jié)論。character_set_system utf8 有關(guān)~~
上述就是小編為大家分享的如何進(jìn)行mysql亂碼產(chǎn)生的探討了,如果剛好有類(lèi)似的疑惑,不妨參照上述分析進(jìn)行理解。如果想知道更多相關(guān)知識(shí),歡迎關(guān)注億速云行業(yè)資訊頻道。
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。