Oracle數據庫字符集問題解析


第一次迭代:掌握字符集方面的基本概念。
有些朋友可能會認爲這是多此一舉,但實際上正是由於對相關基本概念把握不清,才導致了諸多問題和疑問。
首先是字符集的概念。
我們知道,電子計算機最初是用來進行科學計算的(所以叫做“計算機”),但隨着技術的發展,還需要計算機進行其它方面的應用處理。這就要求計算機不僅能處理數值,還能處理諸如文字、特殊符號等其它信息,而計算機本身能直接處理的只有數值信息,所以就要求對這些文字、符號信息進行數值編碼,最初的字符集是我們都非常熟悉的ASCII,它是用7個二進制位來表示128個字符,而後來隨着不同國家、組織的需要,出現了許許多多的字符集,如表示西歐字符的ISO8859系列的字符集,表示漢字的GB2312-80、GBK等字符集。
字符集的實質就是對一組特定的符號,分別賦予不同的數值編碼,以便於計算機的處理。
字符集之間的轉換。字符集多了,就會帶來一個問題,比如一個字符,在某一字符集中被編碼爲一個數值,而在另一個字符集中被編碼爲另一個數值,比如我來創造兩個字符集demo_charset1與demo_charset2,在demo_charset1中,我規定了三個符號的編碼爲:A(0001),B(0010),?(1111);而在demo_charset2中,我也規定了三個符號的編碼爲:A(1001),C(1011),?(1111),這時我接到一個任務,要編寫一個程序,負責在demo_charset1與demo_charset2之間進行轉換。由於知道兩個字符集的編碼規則,對於demo_charset1中的0001,在轉換爲demo_charset2時,要將其編碼改爲1001;對於demo_charset1中的1111,轉換爲demo_charset2時,其數值不變;而對於demo_charset1中的0010,其對應的字符爲B,但在demo_charset2沒有對應的字符,所以從理論上無法轉換,對於所有這類無法轉換的情況,我們可以將它們統一轉換爲目標字符集中的一個特殊字符(稱爲“替換字符”),比如在這裏我們可以將?作爲替換字符,所以B就轉換爲了?,出現了信息的丟失;同樣道理,將demo_charset2的C字符轉換到demo_charset1時,也會出現信息丟失。
所以說,在字符集轉換過程中,如果源字符集中的某個字符在目標字符集中沒有定義,將會出現信息丟失。
數據庫字符集的選擇。
我們在創建數據庫時,需要考慮的一個問題就是選擇什麼字符集與國家字符集(通過create database中的CHARACTER SET與NATIONAL CHARACTER SET子句指定)。考慮這個問題,我們必須要清楚數據庫中都需要存儲什麼數據,如果只需要存儲英文信息,那麼選擇US7ASCII作爲字符集就可以;但是如果要存儲中文,那麼我們就需要選擇能夠支持中文的字符集(如ZHS16GBK);如果需要存儲多國語言文字,那就要選擇UTF8了。
數據庫字符集的確定,實際上說明這個數據庫所能處理的字符的集合及其編碼方式,由於字符集選定後再進行更改會有諸多的限制,所以在數據庫創建時一定要考慮清楚後再選擇。
而我們許多朋友在創建數據庫時,不考慮清楚,往往選擇一個默認的字符集,如WE8ISO8859P1或US7ASCII,而這兩個字符集都沒有漢字編碼,所以用這種字符集存儲漢字信息從原則上說就是錯誤的。雖然在有些時候選用這種字符集好象也能正常使用,但它會給數據庫的使用與維護帶來一系列的麻煩,在後面的迭代過程中我們將深入分析。
客戶端的字符集。
有過一些Oracle使用經驗的朋友,大多會知道通過NLS_LANG來設置客戶端的情況,NLS_LANG由以下部分組成:NLS_LANG=<Language>_<Territory>.<Clients Characterset>,其中第三部分<Clients Characterset>的本意就是用來指明客戶端操作系統缺省使用的字符集。所以按正規的用法,NLS_LANG應該按照客戶端機器的實際情況進行配置,尤其對於字符集一項更是如此,這樣Oracle就能夠在最大程度上實現數據庫字符集與客戶端字符集的自動轉換(當然是如果需要轉換的話)。
總結一下第一次迭代的重點:
字符集:將特定的符號集編碼爲計算機能夠處理的數值;
字符集間的轉換:對於在源字符集與目標字符集都存在的符號,理論上轉換將不會產生信息丟失;而對於在源字符集中存在而在目標字符集中不存在的符號,理論上轉換將會產生信息丟失;
數據庫字符集:選擇能夠包含所有將要存儲的信息符號的字符集;
客戶端字符集設置:指明客戶端操作系統缺省使用的字符集。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章