李曼
(商丘職業(yè)技術(shù)學(xué)院 河南省商丘市 476100)
MySQL數(shù)據(jù)庫技術(shù)是一門非常重要的計(jì)算機(jī)專業(yè)基礎(chǔ)課程,在WEB應(yīng)用方面,同時(shí),由于MySQL的跨平臺性,它可以在Linux、Windows、Netware等20多個(gè)平臺上運(yùn)行。MySQL是一種開放源代碼的關(guān)系型數(shù)據(jù)庫管理系統(tǒng)(RDBMS),它體積小、速度快、總體成本低,所以MySQL是近年來很多中小型網(wǎng)站開發(fā)首要選擇的網(wǎng)站數(shù)據(jù)庫軟件。MySQL數(shù)據(jù)庫系統(tǒng)使用結(jié)構(gòu)化查詢語言(SQL)進(jìn)行數(shù)據(jù)庫管理。我們通過系統(tǒng)分析把現(xiàn)實(shí)世界事物及其聯(lián)系信息化轉(zhuǎn)換為信息世界里的概念模型,再經(jīng)過系統(tǒng)數(shù)據(jù)庫設(shè)計(jì)將我們得到的概念模型轉(zhuǎn)化為計(jì)算機(jī)世界的數(shù)據(jù)模型,這一過程我們就需要使用MySQL數(shù)據(jù)庫系統(tǒng)來實(shí)現(xiàn),我們知道,計(jì)算機(jī)只能識別二進(jìn)制代碼,為了使計(jì)算機(jī)不僅能做科學(xué)計(jì)算,也能處理文字信息,人們想出了給每個(gè)文字符號編碼以便于計(jì)算機(jī)識別處理的辦法,這就是計(jì)算機(jī)字符集產(chǎn)生的原因。這一套文字符號及其編碼、比較規(guī)則的集合[1]會(huì)直接影響數(shù)據(jù)庫中數(shù)據(jù)信息的顯示,可以以我們希望看的的樣式顯示,當(dāng)然也會(huì)以我們不希望看到的一種方式——亂碼來顯示給我們,接下來我們就來探討一下字符編碼為什么會(huì)影響字符的顯示以及亂碼出現(xiàn)的原因及其解決方式。
字符編碼(英文Character encoding)是為了方便文本在計(jì)算機(jī)中存儲并通過通信網(wǎng)絡(luò)進(jìn)行傳遞,把指定集合中某一對象字符集中的字符進(jìn)行編碼。常見的例子包括將拉丁字母表編碼成摩斯電碼和ASCII。其中,ASCII將字母、數(shù)字和其它符號編號,并用7比特的二進(jìn)制來表示這個(gè)整數(shù)。通常會(huì)額外使用一個(gè)擴(kuò)充的比特,以便于以1個(gè)字節(jié)的方式存儲[2]。
在數(shù)據(jù)庫中常見的編碼方式有以下幾種:
(1)Latin編碼方式,這是一種標(biāo)準(zhǔn)字符集(standard character set),支持英文和許多西歐語言。
(2)utf-8編碼方式,這是一種支持大部分語言的字符集,為了提高Unicode的編碼效率,于是就出現(xiàn)了UTF-8編碼。UTF-8可以根據(jù)不同的符號自動(dòng)選擇編碼的長短。比如英文字母可以只用1個(gè)字節(jié)就夠了。
(3)GB2312碼是ANSI編碼的一種,為了滿足國內(nèi)在計(jì)算機(jī)中使用漢字的需要由國家標(biāo)準(zhǔn)總局發(fā)布的一系列字符集國家標(biāo)準(zhǔn)編碼,GB2312是一個(gè)簡體的中文字符集。
(4)GBK即漢字內(nèi)碼擴(kuò)展規(guī)范,K為擴(kuò)展的漢語拼音中“擴(kuò)”字的聲母。關(guān)于字符集、語言等信息文件都存放在MySQL軟件目錄結(jié)構(gòu)下的share文件中[3]。
通過學(xué)習(xí)MySQL數(shù)據(jù)庫我們知道,show的相關(guān)語句內(nèi)容很多, 它的功能就是可以查看很多內(nèi)容,服務(wù)器可以支持多種字符集,比如show character set;這條語句可以列出可用的字符集,show collation可以列出一個(gè)字符集的校對規(guī)則,如果想要查看gb2312字符集的校驗(yàn)規(guī)則,我們就可以使用show collation like 'gb2312%';這里要明確的一點(diǎn)是:字符集并不完全等同于整理規(guī)則, 我們知道同一個(gè)字符集可能有多個(gè)排序規(guī)則,比如latin1 -> latin1_Swedish_Ci, Latin_Spanish_Ci,……因?yàn)橛袝r(shí)我們在代碼里沒有指定collation,這時(shí)就需要指定一個(gè) default collation,Ci表示 case insensitive 大小寫不敏感,cs: case sensitive 大小寫敏感,并不是所有的整理規(guī)則都要使用ci[3]。
如果想要查看各個(gè)字段的整理規(guī)則,可以使用show full columns from tablename這條語句,這里需要重申的是;服務(wù)器、數(shù)據(jù)庫和數(shù)據(jù)表都可以指定“字符集”, 而字段卻不能指定字符集,字段只能指定“整理規(guī)則”,這個(gè)整理規(guī)則中就可以認(rèn)為包含了字段的字符集以及比較/排序規(guī)則,即使前3個(gè)層次的字符集默認(rèn)的 都是 latin1,但是如果字段的字符集整理為 gbk_chinese_ci的話, 也能正常顯示中文[4]。
我們在學(xué)習(xí)了字符集編碼問題后就明白:在顯示器上看見的文字、圖片等信息在計(jì)算機(jī)內(nèi)部存儲的內(nèi)容其實(shí)并不是我們看見的樣子,也就是計(jì)算機(jī)并不是簡單的原樣重現(xiàn)的,即使假如所有的信息都在硬盤中存儲,我們拆開它看到了也只有盤片,沒有我們想看到的數(shù)據(jù)信息。計(jì)算機(jī)硬盤只能用0和1來存儲各種信息,比如小張用1100001來表示A,小李用11000010來存儲A,可能小李用1100001來存儲的是X,那么小張把1100001發(fā)給小李,小李就會(huì)看成X,這就是小張和小李使用了不同的編碼表,不同的編碼表0和1的對應(yīng)關(guān)系不同,當(dāng)然顯示的就是不同結(jié)果,所以在事先交流數(shù)據(jù)信息時(shí),需要明確自己要使用的編碼,或者通過轉(zhuǎn)換編碼,就像翻譯不同語言一樣,才可以實(shí)現(xiàn)無亂碼溝通。
在Windows系統(tǒng)中安裝MySQL數(shù)據(jù)庫軟件時(shí),我們知道MySQL服務(wù)器會(huì)有一個(gè)關(guān)于服務(wù)器字符集和服務(wù)器校驗(yàn)規(guī)則的設(shè)置,而且這兩個(gè)設(shè)置均不能為空,如果選擇默認(rèn)設(shè)置,那么Latin1是MySQL服務(wù)器的默認(rèn)字符集,其對應(yīng)的校驗(yàn)規(guī)則是Latin_Swedish_ci,也 就 是default-character-set=Latin1,collation_server=Latin_Swedish_ci?;谇懊娴慕榻B我們知道,latin1字符集不能編碼中文字符, 所以MySQL控制臺或者返回:“Incorrect string value ......”, 或者返回“Data too long for column ......”,從而導(dǎo)致數(shù)據(jù)插入不成功,即使插入成功也會(huì)在數(shù)據(jù)表里顯示亂碼的現(xiàn)象。
隨著我國計(jì)算機(jī)科學(xué)技術(shù)的飛速發(fā)展,錄入中文信息已經(jīng)變得非常普遍,那么我們在安裝和配置MySQL數(shù)據(jù)庫軟件時(shí)就要考慮到字符編碼的問題,所以在我們配置MySQL服務(wù)器環(huán)境時(shí)就需要將字符集(default-character-set)設(shè)置為gbk,此時(shí)校驗(yàn)規(guī)則就會(huì)自動(dòng)跟gbk字符集匹配,當(dāng)然也可以設(shè)置為 gbk_chinese_ci。這里,簡單介紹一下存在校對規(guī)則命名的約定: 它們以其相關(guān)的字符集名開始, 通常包括一個(gè)語言名, 并且以 _ci( 忽略大小寫) 、_cs( case sensitive, 大小寫敏感) 或 _bin( 二進(jìn)制) 結(jié)束。我們可以根據(jù)需要選擇不同的校驗(yàn)規(guī)則。如果在配置過程中忽略了字符集編碼的問題,那么也不必?fù)?dān)心,我們可以給出以下幾種解決方案:
我們需要使用alter database petstore character set gbk collate gbk_chinese_ci來修改其字符編碼方式,之后在創(chuàng)建數(shù)據(jù)表時(shí)也要保證其字符編碼與其所在的數(shù)據(jù)庫一致??梢允褂肧QL語句show create table 數(shù)據(jù)表表名,如果從開始都是使用默認(rèn)字符集,沒有修改它的編碼方式,此時(shí)極可能查看到該數(shù)據(jù)表的默認(rèn)編碼方式是Latin1,那么我們需要繼續(xù)使用alter語句來修改,具體SQL語句為Alter table 數(shù)據(jù)表 default character set gbk collate gbk_chinese_ci,這是更改表默認(rèn)的字符集的SQL語句。另外,也需要使用上一步的alter database petstore character set gbk collate gbk_chinese_ci把數(shù)據(jù)庫的編碼方式也一并修改了,讓數(shù)據(jù)庫和它其中的數(shù)據(jù)表編碼方式保持統(tǒng)一,都為gbk,當(dāng)然gb2312也是可以的。
還有一種情況就是所有的字符集設(shè)置都是正確的,但仍然有亂碼,這時(shí)應(yīng)該是因?yàn)檫B接級字符集不正確造成的,連接級字符集由character_set_client、character_set_connection、character_set_results三個(gè)變量決定,這時(shí)需要把這三個(gè)變量均設(shè)置為支持中文的字符集,比如設(shè)置為gbk或者gb2312即可??梢匀缦氯龡l命令來改變連接級字符集:
除了上述在DOS環(huán)境下修改字符編碼方式,當(dāng)然也可以在SQLyog圖形編輯器中修改,在左側(cè)數(shù)據(jù)庫目錄里選擇要修改編碼方式的數(shù)據(jù)庫對其右擊,選擇改變數(shù)據(jù)庫,接著在彈出的窗口中修改其基字符集和數(shù)據(jù)庫排序規(guī)則,然后保存更改設(shè)置。
MySQL中文顯示亂碼或者問號是因?yàn)檫x用的編碼不對或者編碼不一致造成的,首先我們可以在安裝配置MySQL環(huán)境時(shí)就選擇其編碼方式為gbk或者gb2312,如果忽略了這一點(diǎn)還有另外一種方法:通過修改my.ini配置文件。通過MySQL文件存放的目錄,打開文件名為my.ini配置文件,找到default-character-set這句配置信息,很顯然這里指明了當(dāng)前數(shù)據(jù)庫環(huán)境的默認(rèn)編碼方式,此時(shí)我們需要將default-character-set設(shè)為gbk(或者gb2312)(有的版本不支持default-character-set=gbk,這時(shí)我們可以使用character_set_server=gbk來取代 default-character-set=gbk即可),修改之后保存文件,通過進(jìn)入Windows服務(wù)管理器啟動(dòng)MySQL服務(wù),重新啟動(dòng)一下該服務(wù);或者以管理員身份運(yùn)行cmd.exe,進(jìn)行如下操作:
關(guān)閉服務(wù) net stop mysql;
開啟服務(wù) net start mysql。
但此處需要注意的是:我們在my.ini文件中修改的defaultcharacter-set字符集只會(huì)對MySQL其自身客戶端起作用,對其他客戶端數(shù)據(jù)庫程序無效,比如如果是通過web頁面顯示的數(shù)據(jù)庫內(nèi)容,開發(fā)人員必須在web程序中指定正確的編碼方式,如果有誤,亂碼就會(huì)顯示在頁面中。設(shè)置成功之后,就可以來查看是否改變了編碼格式。還是在DOS環(huán)境中:
(1)輸入 mysql -u root –p,進(jìn)入MySQL數(shù)據(jù)庫 ;
(2)鍵入密碼:*****(自己的密碼,沒有的話直接回車鍵。);
(3)show variables like 'char%';顯示編碼格式;
進(jìn)入DOS環(huán)境或者sqlyog,這時(shí)通過show語句查看數(shù)據(jù)庫或者數(shù)據(jù)表文件,我們就會(huì)發(fā)現(xiàn)修改已經(jīng)生效,這時(shí)可以通過insert語句試著插入一條中文字符的記錄驗(yàn)證一下。
綜上所述,我們知道MySQL數(shù)據(jù)庫作為全球最受歡迎的數(shù)據(jù)庫平臺,正在擁有越來越多的中文編程環(huán)境用戶,本篇介紹了MySQL數(shù)據(jù)庫中字符編碼的相關(guān)知識,并且指出我們在使用MySQL數(shù)據(jù)庫會(huì)出現(xiàn)的中文亂碼現(xiàn)象的根本原因,通過分析亂碼問題,我們知道這歸根結(jié)底是字符集編碼的問題,我們通過調(diào)試SQL代碼細(xì)節(jié)指出問題所在之處,然后通過實(shí)際操作給出了幾種切實(shí)可行的解決方案,我們只要正確設(shè)置各個(gè)級別的字符集問題,那么亂碼問題就不會(huì)成為我們學(xué)習(xí)中的障礙,這有助于我們更加深入地學(xué)習(xí)MySQL數(shù)據(jù)庫知識。