谢谢GerryYang(轻尘),luxuezhu(卢冲)  如何测试一下呢?

解决方案 »

  1.   

    null不占空间,是字段的属性占用一定的空间
      

  2.   

    字段位null不占索引空间,但占有字段大小的表空间
      

  3.   

    简单萨,建个空表,记录表空间,然后Insert Null进去,看看表空间有变化没有
      

  4.   

    如果null的列是在表的中间占用1字节
    如果是在末尾 不占用
      

  5.   

    如果想深入了解一点oracle存储方面的
    也许我的主页能帮上忙
    http://l2g32003.home4u.china.comhttp://l2g32003.home4u.china.com/block/table_block.html 这个是table的情况 其中我解释了null的情况
      

  6.   

    感谢大家回答我有关null值占不占空间的问题,回去后做了试验:
    这样的一个表结构
    space
    ________________________________
    ID       |       NUMBER(13)
    ________________________________
    NAME     |       VARCHAR(100)
    --------------------------------
    AGE      |       NUMBER(13)做了测试,
    1 往space表中插入20万条记录(ID,NAME,AGE)均非空,space表占据的字节数为9437184 bytes2 drop space表
    3 重建space表
    4 往space表中插入20万条记录(ID,NAME,AGE)均为null,space表占据的字节数为3145728 bytes,各字段值全为null时占的空间是均为非空的1/35 drop space表,并重建表space,修改表结构为
    space
    --------------------------------
    ID       |       NUMBER(13)
    --------------------------------
    NAME     |       VARCHAR(100)
    --------------------------------
    AGE      |       NUMBER(13)
    --------------------------------
    SEX      |       VARCHAR(10)6 往space表中插入20万条记录(ID,NAME,AGE,SEX)均非空,space表占据的字节数为11534336 bytes7 如2,3
    8 往space表中插入20万条记录(ID,NAME,AGE,SEX)均为null,space表占据的字节数为3145728 bytes
    请大家分析一下上面的试验数据,
    为什么步骤8与步骤4得到表占的字节数是一样的呢?
    null占多少字节呢?
    按您所说,如果null的列是在表的中间占用1字节
    如果是在末尾 不占用
    那表的第一列为null占字节吗?期盼得到大家的回复,谢谢
      

  7.   

    当然占了!起码要让数据库知道他是NULL值吧,这当然要解释,就要占空间了
      

  8.   

    dump一下结果是很明显的。
     l2g32003的说法是正确的,不过你不要误解他“如果是在末尾 不占用”这句话。
    所谓末尾是指最后的连续为NULL的列,
    比如有四列:cl1,cl2,cl3,cl4  如果值为值为:1,1,1,null
          那么,末尾就是cl4  如果值为:1,1,null,null
          那么,末尾就是cl3,cl4  如果值全为NULL:null,null,null,null
          那么,末尾就是全部列cl1,cl2,cl3,cl4。除了末尾情况,其它位置NULL都是占1字节
      

  9.   

    关于null是否占空间是这样的:
    当为null的字段在一条记录的最后,就是说他后边没有非null的字段值时,是不占空间的
    当为null的字段在一条记录的中间,就是说他后边还有非null的字段值时,他占一个字节
    所以oracle建议在设计表结构时尽量把可空的字段放到最后!oracle文档中有说明的
      

  10.   

    谢谢大家,我做了如下的试验:space表定义如下:
    A      VARCHAR(10) B      VARCHAR(10) C      VARCHAR(10)
    D      VARCHAR(10) E      VARCHAR(10) F      VARCHAR(10)
    insert into test values (null,null,null,null,null,null);
    insert into test values ('1',null,null,'1',null,'1');
    insert into test values(null,1,null,null,null,1);
    commit;
    提交后使用dunp查看各字段占空间的情况:
    select A,dump(A),B,dump(B) from test;
    得到如下结果:
    A      |  DUMP(A)   |   B   |DUMP(B) 
    -------------------------------------
           |    NULL    |       |  NULL
    -------------------------------------
    1      |Typ=1 Len=1 |       |  NULL 
    -------------------------------------
           | NULL       |   1   |Typ=1 Len=1
    对为null的字段进行dump后得到的结论是不占空间的,您指的null字节占一个字节空间的情况是什么原因?
      

  11.   

    null值用dump()函数是看不出存储状况的.
    ALTER SYSTEM DUMP DATAFILE file_No BLOCK block_No;
    dump出来看trace文件
      

  12.   

    例子:
    SQL> Create Table test (A VARCHAR(10), B VARCHAR(10), C VARCHAR(10),D VARCHAR(10), E VARCHAR(10), F VARCHAR(10));Table createdSQL> insert into test values (null,null,null,null,null,null);1 row insertedSQL> insert into test values ('1',null,null,'1',null,'1');1 row insertedSQL> insert into test values(null,1,null,null,null,1);1 row insertedSQL> COMMIT;Commit completeSQL>  SELECT SQCTEST.GET_ROWID(ROWID) FROM TEST;SQCTEST.GET_ROWID(ROWID)
    --------------------------------------------------------------------------------
    Object# is      :43637
    Relative_fno is :18
    Block number is :410671
    Row number is   :0Object# is      :43637
    Relative_fno is :18
    Block number is :410671
    Row number is   :1Object# is      :43637
    Relative_fno is :18
    Block number is :410671
    Row number is   :2
    SQL> ALTER SYSTEM DUMP DATAFILE 18 BLOCK 410671;System altered
    下面是trace结果的一部分:
    block_row_dump:
    tab 0, row 0, @0x1f95
    tl: 3 fb: --H-FL-- lb: 0x1  cc: 0     //这是第一行数据长度TL是3,CC存储列数是0。(这就是全部为NULL的记录,没有记录任何NULL值)
    tab 0, row 1, @0x1f89
    tl: 12 fb: --H-FL-- lb: 0x1  cc: 6    //这是第二行数据长度TL是12=3+2+1+1+2+1+2,CC存储列数是6。(记录了中间三个NULL值,每个为1)
    col  0: [ 1]  31
    col  1: *NULL*
    col  2: *NULL*
    col  3: [ 1]  31
    col  4: *NULL*
    col  5: [ 1]  31
    tab 0, row 2, @0x1f7e
    tl: 11 fb: --H-FL-- lb: 0x1  cc: 6  //这是第三行数据长度TL是11=3+1+2+1+1+1+2,CC存储列数是6。(记录了中间四个NULL值,每个为1)
    col  0: *NULL*
    col  1: [ 1]  31
    col  2: *NULL*
    col  3: *NULL*
    col  4: *NULL*
    col  5: [ 1]  31
    end_of_block_dump
      

  13.   

    to hippie1024(痞子) 
    谢谢,请您再解释一下,
    SELECT SQCTEST.GET_ROWID(ROWID) FROM TEST;//SQCTEST.GET_ROWID(ROWID)ALTER SYSTEM DUMP DATAFILE 18 BLOCK 410671;// 18,410671代表什么以及如何查看trace文件,谢谢,太感谢了
      

  14.   

    18代表的是数据文件id,可以根据dba_data_files查看对应的数据文件
    410671代表block_id
    这些信息你也可以通过dba_extents获取
      

  15.   

    GET_ROWID(ROWID)是我自己的一个函数,把ROWID分解成四部分解释。另:dba_extents中的BLOCK_ID是head block,一般需要+1得到我们的数据的block,
          如果在ASSM下就要+6
      

  16.   

    GET_ROWID()是我自己的函数:
    create or replace function get_rowid
    (l_rowid in varchar2)
    return varchar2
    is
    ls_my_rowid  varchar2(200);          
    rowid_type  number;          
    object_number  number;          
    relative_fno  number;          
    block_number  number;          
    row_number  number;  
    begin
     dbms_rowid.rowid_info(l_rowid,rowid_type,object_number,relative_fno, block_number, row_number);          
     ls_my_rowid := 'Object# is      :'||to_char(object_number)||chr(10)||
    'Relative_fno is :'||to_char(relative_fno)||chr(10)||
    'Block number is :'||to_char(block_number)||chr(10)||
    'Row number is   :'||to_char(row_number);
     return ls_my_rowid ;
    end;
    /18 , 410671 分别对应函数输出的数据文件号relative_fno ,数据blockid:block_number