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