[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/