塗抹MySQL--第6章 開源運動與開源軟體MySQL - 6.1字符集和校對規則

junsansi發表於2014-07-15

字符集這個東西對於資料庫中儲存的資料來說非常之重要,特別是對於中文環境這類多位元組編碼的字元尤其特殊,設定不當就極有可能遇到亂碼的情況。基於此,儘管我完全理解大家恨不能馬上就進入到MySQL資料庫中,施展拳腳的急迫心情,不過在此之前,我覺著還是有必要先讓大家認識MySQL中的字符集設定。下面三思簡單通過三五個(///)字跟大家闡述一下,MySQL資料庫中的字符集概念和應用。

本章文字內容較多,對於有失眠/多動症/拖延症/強迫症等症狀的朋友應有所幫助,歡迎大家對號入座,走過路過不錯過。另外,為了更好的促進您中午的睡眠,友情推薦大家可以在午飯後閱讀,根據三思本人在營養學方面的造詣,飯後腸胃蠕動所耗費的大量能量,會使得大腦供氧有明顯下降,值此大腦昏沉之際研討枯燥文字,哎呀,想不睡著都難吶~

6.1 基礎掃盲

提到字符集(Character Set),我們首先一定要搞明白,“字符集”到底是針對什麼,應該怎麼理解,我覺著很多人對這個問題模模糊糊的根本原因,實際上就是沒能正確理解“字符集”的根本含義。

做為光榮的社會主義無產階級接班人(俗稱屌絲),我們首先拿起馬列主義、毛澤東思想等重要武器,高舉三個代表的偉大旗幟深入認識和學習一下字符集這個概念,思想的力量是巨大的,帶表的成就感是非凡的。可是,我們畢竟年紀輕資歷淺,短時間內無法消化和理解,不得已,只好再嘗試從最簡單的語法上分析,字符集針對的是什麼,這個時候一定要注意了,接下來面對的是實際問題,千萬不要想的過於複雜,就從最簡單的字面意義理解就好。

那麼所謂字符集,針對的是“字元”,這樣說對不對呢,絕對沒有問題。但是也要正確的理解"字元"的概念,提到字元那麼很多人會想什麼不是字元呢,"abc"是字元,"123"也是字元,本書中出現的每個符號都是字元。MySQL中的所謂字符集設定,是針對這些字元嗎,我可以負責任的告訴大家,不是,絕對不是。字符集中所謂的"字元"並不是指字元這個形容詞,實際上說的是“字元”型別。

MySQL資料庫提供了多種資料型別的支援,什麼數值型、日期型、二進位制型別等等都不需要設定字符集,MySQL資料庫中所謂字符集設定,主要是指標對字元型別的設定,比如charvarchartext這類字元型的資料型別。讀者朋友們,注意了,本章中當我們再提到字符集時(這裡並不僅僅侷限於MySQL資料庫,其它如ORACLE/MSSQL/DB2等都是同理),如非特別註明,所說的均是指字元型別儲存字元的格式。

MySQL資料庫中對字符集設定的支援非常全面,即使相比ORACLE這種大型資料庫軟體也毫不遜色,甚至還更為靈活,它提供了多種粒度適應不同的場合和需求,使用者可以在伺服器、資料庫、表甚至列一級進行設定,同時登入到MySQL資料庫的會話及應用程式連線中也可以進行個性化設定,MySQL中的包括MyISAMMEMORY以及InnoDB等常用儲存引擎均能支援。

大家必須要認識到,字符集並不僅僅對儲存的資料有效,在客戶端連線伺服器端時也與字符集有關。這好像是廢話,你想,即然儲存的資料有字符集的因素,那麼不管客戶端準備查詢還是儲存這些資料,肯定也會與字符集有關係的。話是這麼說對吧,但對於很多資料庫管理員,他們其實更多是“資料庫軟體”的管理者,對其中儲存的資料介入程度並不深,這種情況下呢,一般預設字符集就能夠滿足其操作需求,如果環境需要,不能使用預設的字符集,MySQL也提供了相應的方式,單獨設定當前會話的字符集,後面具體小節中會講到這一點。

好了,基本情況大家已經都瞭解了,接下來就讓三思多花些筆墨描述,主動幫助大家kick到下一層夢鏡,好讓大家能夠睡的更深沉。

6.1.1 關於字符集

先來明確最核心的概念性問題,資料庫中的字符集究竟是什麼?還是問字符集的問題,但是角度有所不同。其實簡單講在資料庫看來,字符集就是各種字元編碼的一個集合。對於資料庫來說,即使是同一個字元,不同的字符集在處理時它的編碼格式都有可能不同(廢話啊,如果相同,那就沒必要搞多種字符集了),那麼問題緊跟著就來了,為什麼要搞多種字符集呢,此事就說來話長了,不過考慮到我們這本書畢竟不是在做歷史考據,太無關的事情扯進來,搞不好就把讀者朋友們直接kickLimbo,那得坐多少站才能回的來啊,所以長話短說吧。

舉個例子描述:同樣是黑白膚色的大熊貓科動物,擱在大陸叫大熊貓,到臺灣就說貓熊,到了美國又改叫panda,你要是跑非洲去,沒有這種動物,可能都找不出對應的形容詞(於是亂碼了),對於熊貓來說它自身沒發生什麼變化,所產生的不同稱謂的變化,實際上是與地域有很大關聯,那麼如果把當地擁有的各種詞彙集合組成一本字典,對應過來的話,這個字典就是所謂的字符集了(此說並不嚴謹,本例僅為幫助理解)

如果要下一個更書面化的定義,那麼,字符集就是指符號和字元編碼的集合。

不同地方的字典當然有可能是不同的,甚至每本字典中的詞彙量都不一致,找一本適合的字典非常重要,比如說你給不懂中文的美國朋友看熊貓倆字,它絕對不可能關聯到那個毛茸茸的可愛的永遠掛著黑眼圈的珍稀動物。

在資料庫中應用字符集時,對於具體字符集的設定同理也非常的重要,為了能讓字元正確的被儲存,同時還能正確的被讀取出來,到最終正確的顯示給使用者,這中間每一個環節都涉及到字符集(以及可能發生的轉換),只有讀和寫時,會話所用字符集相互匹配(或者說相容),最終顯示的結果才會正確無誤,否則,就會出現不希望看到,但可能又確實常見的現象:亂碼。但是,不要怕,只要本章的內容認真閱讀,深入理解,您就可以跟亂碼說拜拜。

6.1.2 關於校對規則

MySQL資料庫中提到字符集,有一個關聯的關鍵詞是絕對不可被忽略的,那就是校對規則(Collation),官方文件中對此所做的名詞解釋如下:校對規則:顧名思義,就是指定義的一種比較字符集中字元的規則。也有些資料中將其稱為排序規則。

字符集想必大家已經理解,那麼校對規則又是怎麼一回事兒呢,上面提到的這些概念聽起來比較抽象,那麼三思還是通過示例來描述吧,應該能夠更加清晰一些。

比如我們儲存了下列字元到物件的某列中,有“A,B,a,b”四個字元,然後再為上述的每個字元都定義一個數值:A0表示,B1表示,a2表示,b3表示。

就這個例子來說,A做為一個符號,與其對應的0就是A的編碼後的形式,上述這四個字元以及其編碼形式的組合,就是前面所說的字符集。那麼哪部分指的是校對規則呢,其實腦袋瓜稍靈活一點兒的此時應該也能猜出來,下面就讓三思來揭曉迷底吧。

仍以上面的例子來說明,如果我們希望比較多個字元的值,最簡單的方式當然就是按照定義好的規則直接對比其編碼,按照前面定義的規則,由於01要小,因此我們說AB小,應用比較的這個規則,就是所謂的校對規則,說的簡單點,校對規則的核心就是比較字元編碼的方式。

前例中只應用了一項比較的規則,我們將這類最簡單的,比較所有可能性的校對規則,稱為二元(Binary)校對規則。還有些比較複雜的校對規則,比如說大小寫等同的規則,在比較時,就需要首先將"a,b"視為等同於"A,B",而後再比較編碼(相當於應用了兩項規則),這種規則我們被之為大小寫不敏感(case-insensitive)校對規則,與之對應當然也會有大小寫敏感的校對規則,這類規則相對來說要比二元校對規則複雜。

       上面所提到的這兩種規則,只是字符集的校對規則的最常見形式,實際上排序的規則很多很複雜,因為我們平常接觸到的字元並不僅只是abcd這類單位元組的英文字母,還包括單詞,各種符號以及多位元組的字元(更加複雜)等等,很多的校對規則都擁有一堆的規則,不僅僅是大小寫不敏感,還有比如像漢字中的多音字等等,在真正的現實生活中,即使是聲稱具有高等智慧的人類處理這些有時候也暈頭轉向啊。比如像三思這種普通話堪稱媲美某AV臺播音員的人物,要是給扔到廣東也立馬變聾啞,您要是把我扔到美國......親,我都準備好了,您什麼時候扔。

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/7607759/viewspace-1219106/,如需轉載,請註明出處,否則將追究法律責任。

相關文章