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

Oracle基本數據類型存儲格式淺析(一)-字符類型

2013-11-13 22:10:25  來源: Oracle 

  前一陣看完文檔對oracle的基本數據類型的存儲格式有了一些了解最近有做了一些測試進行了驗證

  打算整理總結一下這一篇主要說明字符類型的存儲格式主要包括charvarchar和long等幾種類型

  SQL> create table test_char (char_col char() varchar_col varchar() long_col long);

  表已創建

  SQL> insert into test_char values (abc fd);

  已創建

  SQL> commit;

  提交完成

  SQL> select rowid from test_char;

  ROWID

AAABLAAFAAAAAgAAA

  根據rowid的定義規則位是表示的是數據文件F表示位表示的是在這個數據文件中的第幾個BLOCKg表示(rowid編碼相當於進制用A~Z a~z ~ + /共個字符表示A表示B表示……a表示……表示……+表示/表示

  我們根據計算的結果去dump這個block

  SQL> ALTER SYSTEM DUMP DATAFILE BLOCK ;

  系統已更改

  打開產生的trace文件

  data_block_dumpdata header at x
===============
tsiz: xf
hsiz: x
pbl: x
bdba: x
    
flag=
ntab=
nrow=
frre=
fsbo=x
fseo=xf
avsp=xfe
tosp=xfe
xe:pti[] nrow= offs=
x:pri[] offs=xf
block_row_dump:
tab row @xf
tl: fb: HFL lb: x  cc:
col  : [
col  : [
col  : [ c
end_of_block_dump
End dump data blocks tsn: file#: minblk maxblk

  觀察dump出來的結果可以發現以下幾點

  對於每個字段除了保存字段的值以外還會保存當前字段中數據的長度而且oracle顯然沒有把字段的長度定義或類型定義保存在block中這些信息保存在oracle的數據字典裡面

   根據dump的結果可以清楚的看到字符類型在數據庫中是以ascii格式存儲的

  SQL> select chr(to_number( xx)) from dual;

  CH

a

  char類型為定長格式存儲的時候會在字符串後面填補空格而varchar和long類型都是變長的

  SQL> SELECT DUMP(CHAR_COL ) D_CHAR FROM TEST_CHAR;

  D_CHAR

Typ= Len=:

  SQL> SELECT DUMP(VARCHAR_COL ) D_VARCHAR FROM TEST_CHAR;

  D_VARCHAR

Typ= Len=:

  SQL> SELECT DUMP(LONG_COL ) D_VARCHAR FROM TEST_CHAR;
SELECT DUMP(LONG_COL ) D_VARCHAR FROM TEST_CHAR
            *
ERROR 位於第 行:
ORA: 非法使用 LONG 數據類型

  由於DUMP不支持LONG類型因此我們使用了alter system dump block的方式通過比較兩種方式得到的結果發現DUMP()函數不但方便結果清晰而且指出了進行DUMP的數據類型在以後的例子中除非必要的情況否則都會采用DUMP()函數的方式進行說明

  下面看一下插入中文的情況首先看一下數據庫的字符集

  SQL> select name value$ from sysprops$ where name like %CHARACTERSET%;

  NAME                           VALUE$

NLS_CHARACTERSET               ZHSGBK
NLS_NCHAR_CHARACTERSET         ALUTF

  SQL> insert into test_char values (定長 變長 null);

  已創建

  SQL> SELECT DUMP(CHAR_COL ) D_CHAR FROM TEST_CHAR;

  D_CHAR

Typ= Len=:
Typ= Len=: baba

  SQL> SELECT DUMP(VARCHAR_COL ) D_VARCHAR FROM TEST_CHAR;

  D_VARCHAR

Typ= Len=:
Typ= Len=: beba

  根據dump結果可以清楚的看出普通英文字符和標點用一個字節表示而中文字符或中文標點需要兩個字節來表示

  下面對比一下nchar和nvarchar與charvarchar類型有什麼不同

  SQL> create table test_nchar (nchar_col nchar() nvarchar_col nvarchar());

  表已創建

  SQL> insert into test_nchar values (nchar定長 nvarchar變長);

  已創建

  從這裡已經可以看出一些不同了如果按照剛才中文的計算方法nvarchar變長的長度是+*=已經超過了數據類型定義的大小可是為什麼插入成功了?

  還是dump一下看看結果吧

  SQL> select dump(nchar_col ) from test_nchar;

  DUMP(NCHAR_COL)

Typ= Len=: ebaf

  SQL> select dump(nvarchar_col ) from test_nchar;

  DUMP(NVARCHAR_COL)

Typ= Len=: edf

  這下就明白了雖然仍然是采用ascii碼存儲但是nchar使用的ALUTF字符集編碼長度變為個字節這樣中文使用兩個字節對於可以用一個字節就表示的英文字符采用了高位補的方式湊足這樣對於采用ALUTF字符集的nchar類型無論中文還是英文都用位字符表示因此nvarchar變長的長度是並沒有超過數據類型的限制


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