熱點推薦:
您现在的位置: 電腦知識網 >> 編程 >> Oracle >> 正文

Oracle在數據轉儲時的字符集問題

2013-11-13 16:11:50  來源: Oracle 

  作為一個Oracle數據庫的用戶對於Export和Import兩個命令絕對不會感到陌生因為這二者正是我們經常用於數據備份和恢復的工具但在使用這兩個命令過程中所發生的Oracle字符集問題常給一些Oracle使用者帶來不必要的麻煩和不必要的數據損失本文將就Export和Import過程中Oracle字符集的轉換規律及使用這兩個命令的注意事項做一總結
  字符集轉換的原因
  
  ExportImport過程如上圖所示從這個示意圖中可以看到有四處關系到字符集而這四處字符集的不一致恰恰是導致Oracle進行字符集轉換的原因
  * 源數據庫字符集
  * Export過程中用戶會話字符集
  * Import過程中用戶會話字符集
  * 目標數據庫字符集
  在Export和Import過程中如果存在影響字符集轉換的四因素不一致則可能發生Oracle字符集轉換
  在Export過程中如果源數據庫字符集與Export用戶會話字符集不一致會發生字符集轉換並在導出的二進制格式Dmp文件的頭部幾個字節中存儲Export用戶會話字符集的ID號在這個轉換過程中可能發生數據的丟失
  例: 如果源數據庫使用ZHSGBK而Export用戶會話字符集使用USASCII由於ZHSGBK是位字符集而USASCII是位字符集這個轉換過程中中文字符在USASCII中不能夠找到對等的字符所以所有中文字符都會丟失而變成?? 形式即這種轉換後生成的Dmp文件已經發生了數據丟失
  例: 如果源數據庫使用ZHSGBK而Export用戶會話字符集使用ZHSCGB但由於ZHSGBK字符集是ZHSCGB字符集的超集這個過程中絕大部分字符都能夠正確轉換只有一些超出ZHSCGB字符集的字符變為?? 形式如果源數據庫使用ZHSCGB字符集而Export用戶會話使用ZHSGBK字符集則轉換過程能夠完全轉換成功
  在Import向目標數據庫轉換過程中其字符集發生轉換的情況正好與Export過程相反這裡不再詳述
  在Export導出的Dmp文件中含有Export用戶會話字符集在Import過程中首先發生的是Dmp文件字符集(即Export用戶會話字符集)向Import用戶會話字符集的轉換如果這個轉換過程不能正確完成Import向目標數據庫的導入過程也就不能完成
  進行字符集的正確轉換
  通常情況下我們在使用Oracle的Export和Import過程中並不希望發生字符的轉換但有時這種轉換卻是必要的如我們在安裝Oracle數據庫時選擇ZHSCGB字符集由於這種字符集是一種中文小字符集對於一些漢字不能夠正確表示這需要通過使用ZHSGBK字符集得到解決此時就要進行字符集的轉換
  為了確保ExportImport過程中Oracle字符集不發生轉換或正確轉換建議最好在進行這個過程前檢查一下源數據庫字符集與Export用戶會話字符集是否一致源數據庫字符集與目標數據庫字符集是否一致目標數據庫字符與Import用戶會話字符集是否一致如果能夠保證這四個字符集是一致的則在ExportImport過程中Oracle字符集就不用發生轉換
  可用以下辦法檢查數據庫字符集:
  通過InitXXXXora文件進行查看
  借助SQL語句查看 SELECT NAMEVALUE$ FROM SYSPROPS$ WHERE NAME=NLS_CHARACTERSET
  對於ExportImport用戶會話字符集在Windows系統中也可以通過注冊表中的NLS_LANG進行查看或修改對於Unix系統則可通過設置用戶的環境變量NLS_LANG來查看或修改
  特別要注意的是Oracle數據庫字符集通常是在創建時確定一旦存儲用戶數據後就不要再修改了因為其數據都是使用該字符集進行存儲的改換其他字符集之後原有數據就不能夠正確表示了但如果確實想進行字符集改變則可通過以下幾步來實現
  備份數據庫後刪除原數據(可物理備份如使用Export請注意確保字符集不發生轉換或數據無損失)
  使用Internal用戶更新sysprops$表中的字符集:
  Update sysprops$ set name=DestCharSet Where name=NLS_CHARACTERSET; COMMIT;
  重啟數據庫
  恢復數據
  下面字符集之間的轉換是可行的
  字符集子集向字符集父集轉換是可行的如ZHSCGB向ZHSGBK轉換而字符集父類向字符集子集進行轉換時會損失部分數據
  只包含英文字符數據的雙字節字符集也可向單字節字符集轉換如ZHSGBK(English Only)可以向USASCII正確轉換
  編碼范圍相同的單字節字符集之間通常可以進行相互轉換
  請注意這裡所說的沒有數據損失是指一種字符集A轉換成另一種字符集B之後可以再從字符集B正確轉換成字符集A或字符集B能夠正確表示字符集A中轉換過來的數據
  字符集對程序的影響
  根據一個字符需要多少位字節來表示可以把字符集分為單字節字符集和多字節字符集其中單字節字符集又分為位字符集和位字符集單字節位編碼字符集有USASCⅡ單字節位編碼字符集有符合ISO 標准規定的WEISOP多字節編碼又分為固定長度(長度大於或等於)編碼模式和不固定長度編碼模式多字節編碼字符集中的ZHSGBKZHSCGBJASJIS等是采用兩個字節表示一個字符的字符集又叫雙字節字符集
  一個英文字母是一個字符一個中文漢字是幾個字符呢?我們知道一個中文漢字是雙字節字符但它有幾個字符與其數據庫字符集有關如果數據庫字符集使用單字節USASCII則一個中文漢字是二個字符如果數據庫字符集使用雙字節字符集ZHSGBK則一個中文漢字是一個字符有關這一點可以使用Oracle的函數Substr得到證明
  使用USASCⅡ字符集時:
  Select substr(東北大學) from dual;
  語句執行結果返回
  使用ZHSGBK字符集時:
  Select substr(東北大學) from dual;
  語句執行結果返回東北
  選擇合適的數據庫字符集
  選擇數據庫字符集時應考慮以下事項
  .數據庫需要支持什麼語言
  在為數據庫選擇字符集時常會發現幾種字符集都適合你當前語言需求如簡體中文就有ZHSGBK和ZHSCGB等字符集可供選擇應選擇哪種?在選擇字符集時應考慮到數據庫將來的系統需求如果知道將來數據庫要擴展支持不同的語言選擇一個范圍較廣的字符集會是一個更好的主意
  .系統資源與應用之間的互作用性
  選擇的數據庫字符集應保證操作系統與應用之間的無縫連接如果選擇的字符集不是操作系統有效的字符集則系統就需要在這兩者之間做字符轉換在這種字符轉換過程中就有可能發生一些字符丟失現象從一種字符集A向另一種字符集B轉換過程中A中的字符必須在B中可以找到等價的字符否則就會以來代替從這個意義上說如果兩種字符集編碼范圍是相同的則可以相互轉換
  字符集轉換過程中會影響系統性能因此應保證客戶端和服務器端有相同的字符集以避免字符集轉換也可以提高一定的系統性能
  .系統的性能要求
  不同的數據庫字符集對於數據庫的性能是有一定影響的為了得到最好的數據庫性能選擇的數據庫字符集應避免字符轉換並且要選擇對於期望的語言有最高效的編碼效率通常單字節字符集比多字節字符集有更優的性能表現在空間需求方面也更小些
  .其他一些限制
  在為數據庫選擇一個合適的字符集時應參考Oracle對應版本的相關文檔檢查Oracle對於一些字符集的限制如Oracle 版本中以下字符集是不能使用的: JAEUCFIXEDZHSGBKFIXEDJADBCSFIXEDKODBCSFIXEDZHSDBCSFIXEDJASJISFIXEDZHTTRISFIXED
  綜上所述正確理解Oracle字符集的轉換過程可以使我們避免不必要的麻煩和數據損失合理利用Oracle字符集的轉換過程也可以幫助我們正確地從一種字符集轉換到另一種字符集以滿足我們各種不同的應用需求

From:http://tw.wingwit.com/Article/program/Oracle/201311/17956.html
    推薦文章
    Copyright © 2005-2013 電腦知識網 Computer Knowledge   All rights reserved.