[20160619]NULL在資料庫的儲存.txt

lfree發表於2016-06-20

[20160619]NULL在資料庫的儲存.txt

--簡單探究NULL在資料庫的儲存.這也是別人前幾天問的問題,我自己學習oracle這麼久,也沒有仔細觀察過.

1.環境:
SCOTT@test01p> @ ver1

PORT_STRING                    VERSION        BANNER                                                                               CON_ID
------------------------------ -------------- -------------------------------------------------------------------------------- ----------
IBMPC/WIN_NT64-9.1.0           12.1.0.1.0     Oracle Database 12c Enterprise Edition Release 12.1.0.1.0 - 64bit Production              0

create table t (a number,b number , c number , d number );
insert into t values (1,NULL,NULL,NULL);
insert into t values (2,NULL,2,2);
commit ;
alter system checkpoint ;

2.測試:

SCOTT@test01p> select rowid,t.* from t;
ROWID                       A          B          C          D
------------------ ---------- ---------- ---------- ----------
AAAZpSAAJAAAACNAAA          1
AAAZpSAAJAAAACNAAB          2                     2          2

SCOTT@test01p> @ rowid AAAZpSAAJAAAACNAAA
    OBJECT       FILE      BLOCK        ROW DBA                  TEXT
---------- ---------- ---------- ---------- -------------------- ----------------------------------------
    105042          9        141          0 9,141                alter system dump datafile 9 block 141 ;

SCOTT@test01p> alter system dump datafile 9 block 141 ;
System altered.

data_block_dump,data header at 0xa7e8264
===============
tsiz: 0x1f98
hsiz: 0x16
pbl: 0x0a7e8264
     76543210
flag=--------
ntab=1
nrow=2
frre=-1
fsbo=0x16
fseo=0x1f85
avsp=0x1f6c
tosp=0x1f6c
0xe:pti[0]    nrow=2    offs=0
0x12:pri[0]    offs=0x1f92
0x14:pri[1]    offs=0x1f85
block_row_dump:
tab 0, row 0, @0x1f92
tl: 6 fb: --H-FL-- lb: 0x1  cc: 1
col  0: [ 2]  c1 02
tab 0, row 1, @0x1f85
tl: 13 fb: --H-FL-- lb: 0x1  cc: 4
col  0: [ 2]  c1 03
col  1: *NULL*
col  2: [ 2]  c1 03
col  3: [ 2]  c1 03
end_of_block_dump
End dump data blocks tsn: 3 file#: 9 minblk 141 maxblk 141

--從轉儲可以發現如果插入NULL在後面的欄位,oracle是不儲存的.可以發現col  1: *NULL* ,但是具體數值是多少呢?從這裡看不出來.
--最簡單的方法是透過bbed觀察:

BBED> set dba 9,142
        DBA             0x0240008e (37748878 9,142)

--注:我在windows下使用bbed存在1個資料塊的偏移.
BBED> p *kdbr[1]
rowdata[0]
----------
ub1 rowdata[0]                              @8169     0x2c

BBED> x /r
rowdata[0]                                  @8169
----------
flag@8169: 0x2c (KDRHFL, KDRHFF, KDRHFH)
lock@8170: 0x01
cols@8171:    4

col    0[2] @8172:  0xc1  0x03
col    1[0] @8175: *NULL*
col    2[2] @8176:  0xc1  0x03
col    3[2] @8179:  0xc1  0x03

--可以col    1[0] @8175: *NULL*,裡面的長度是0,也就是NULL不佔用空間,但是長度指示器儲存的是0.但是如果使用dump觀察:

BBED> set count 32
        COUNT           32

BBED> dump /v
File: D:\APP\ORACLE\ORADATA\TEST\TEST01P\SAMPLE_SCHEMA_USERS01.DBF (9)
Block: 142                                            Offsets: 8169 to 8191     Dba:0x0240008e
------------------------------------------------------------------------------------------------------
2c010402 c103ff02 c10302c1 032c0101 02c10201 06b8b0                             l ,...?..?.?,...?..赴
              ~~   
<48 bytes per line>
--注意看~部分.

BBED> set count 1
        COUNT           1

BBED> dump /v offset 8175
File: D:\APP\ORACLE\ORADATA\TEST\TEST01P\SAMPLE_SCHEMA_USERS01.DBF (9)
Block: 142                                           Offsets: 8175 to 8175      Dba:0x0240008e
-----------------------------------------------------------------------------------------------------
ff                                                                              l .
<48 bytes per line>

--可以發現實際上NULL在oracle資料庫使用0xff表示.沒有長度指示器.
--也就是在rowdata中長度指示器等於0xff,就表示長度=0,內容是NULL.

--也可以參考我以前寫的blog,連結如下:

[20121026]varchar2(4000)如何儲存.txt http://blog.itpub.net/267265/viewspace-747304/
1.如果列值長度小於等於250位元組,Oracle使用1位元組儲存其列長.內容為欄位的長度.
2.如果列值長度超過250位元組,則使用3位元組儲存其列長。前面1個位元組使用0xfe(表示超過250),後面2個位元組表示列值長度.

[20140512]關於降序索引.txt          http://blog.itpub.net/267265/viewspace-1159181/

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

相關文章