• NULL在SQLServer数据库数据文件中的存储


    这个对于定长和不定长字段来说是两个结果
    定长字段Null要占足字段空间,不定长字段则不占空间,两者都是通过null_bitmap来确认行数据中的null列。这个很容易用事实表的大小来验证。其具体存储机制还是需要dbcc来查看数据页。我们分几种情况查看:


    -- 定长测试:

    -- 建立测试环境

    create database dbtest111

    go

    use dbtest111

    go

    create table t1( id char ( 10) , name char ( 10))

    insert into t1 select 'a' , '1'

    insert into t1 select 'b' , '2'

     

    create table t2( id char ( 10) , name char ( 10))

     

    insert into t2 select 'a' , 'jinjazz1'

    insert into t2 select 'b' ,null

    insert into t2 select 'c' ,null

    insert into t2 select 'd' , 'jinjazz2'

    go

    -- 运行此命令

    dbcc ind( dbtest111, t2, 0)

    -- 得到 pagetype=1 的那个行数据的 pageid ,比如我这里是

     

    dbcc traceon( 3604)

    dbcc page( dbtest111, 1, 89, 1)

     

    运行上面的sql语句,创建测试环境和实验脚本。得到如下结果

    Slot 0, Offset 0x60, Length 27, DumpStyle BYTE

    Record Type = PRIMARY_RECORD        Record Attributes =  NULL_BITMAP  
    Memory Dump @0x5655C060

    00000000:  10001800 61202020 20202020 20206a69 †....a        ji      
    00000010:  6e6a617a 7a312020 0200fc †††††††††††††njazz1  ...            

    Slot 1, Offset 0x7b, Length 27, DumpStyle BYTE

    Record Type = PRIMARY_RECORD        Record Attributes =  NULL_BITMAP  
    Memory Dump @0x5655C07B

    00000000:  10001800 62202020 20202020 20206a69 †....b        ji      
    00000010:  6e6a617a 7a312020 0200fe †††††††††††††njazz1  ...            

    Slot 2, Offset 0x96, Length 27, DumpStyle BYTE

    Record Type = PRIMARY_RECORD        Record Attributes =  NULL_BITMAP  
    Memory Dump @0x5655C096

    00000000:  10001800 63202020 20202020 20206a69 †....c        ji      
    00000010:  6e6a617a 7a312020 0200fe †††††††††††††njazz1  ...            

    Slot 3, Offset 0xb1, Length 27, DumpStyle BYTE

    Record Type = PRIMARY_RECORD        Record Attributes =  NULL_BITMAP  
    Memory Dump @0x5655C0B1

    00000000:  10001800 64202020 20202020 20206a69 †....d        ji      
    00000010:  6e6a617a 7a322020 0200fc †††††††††††††njazz2  ...

     

    每个slot都代表一行,可以看到null的不但占用空间,而且还写入了你不要的东西,最后处理是通过红色字体部分来判断那些字段是null哪些不是null,红色部分就是null_bitmap


    --2 、不定长字段测试

     

    create database dbtest111

    go

    use dbtest111

    go

    create table t2( id char ( 10) , name varchar ( 10))

     

    insert into t2 select 'a' , 'jinjazz1'

    insert into t2 select 'b' ,null

    insert into t2 select 'c' ,null

    insert into t2 select 'd' , 'jinjazz2'

    go

    -- 运行此命令

    dbcc ind( dbtest111, t2, 0)

    -- 得到 pagetype=1 的那个行数据的 pageid ,比如我这里是

     

     

    dbcc traceon( 3604)

    dbcc page( dbtest111, 1, 73, 1)

     

    运行以上SQL代码得到结果

     

    00000000:  30000e00 61202020 20202020 20200200 †0...a        ..      
    00000010:  fc01001d 006a696e 6a617a7a 31††††††††.....jinjazz1          

    Slot 1, Offset 0x7d, Length 17, DumpStyle BYTE

    Record Type = PRIMARY_RECORD        Record Attributes =  NULL_BITMAP  
    Memory Dump @0x5655C07D

    00000000:  10000e00 62202020 20202020 20200200 †....b        ..      
    00000010:  fe†††††††††††††††††††††††††††††††††††.                      

    Slot 2, Offset 0x8e, Length 17, DumpStyle BYTE

    Record Type = PRIMARY_RECORD        Record Attributes =  NULL_BITMAP  
    Memory Dump @0x5655C08E

    00000000:  10000e00 63202020 20202020 20200200 †....c        ..      
    00000010:  fe†††††††††††††††††††††††††††††††††††.                      

    Slot 3, Offset 0x9f, Length 29, DumpStyle BYTE

    Record Type = PRIMARY_RECORD        Record Attributes =  NULL_BITMAP VARIABLE_COLUMNS

    Memory Dump @0x5655C09F


    00000000:  30000e00 64202020 20202020 20200200 †0...d        ..      
    00000010:  fc01001d 006a696e 6a617a7a 32††††††††.....jinjazz2

     

    varchar比char节省地方,他的rowoffset是依次写入的,null不占用空间,空间利用很好,这个比char字段的null节省地方。


    --3 、不定长字段更改

     

    update t2 set name = 'jinjazz3' where id= 'b'

    dbcc page( dbtest111, 1, 73, 1)

     

    /*

    Row - Offset                      

    3 (0x3) - 159 (0x9f)              

    2 (0x2) - 142 (0x8e)              

    1 (0x1) - 188 (0xbc)                

    0 (0x0) - 96 (0x60) 

    */  

     

    这个只要看最后的row Offset,红色部分是update的这条,他开辟了另外一处空间把null变成了非null。

    当然系统会适时回收老的废弃空间。但varchar的效率没有char高是肯定的了,这也就是说char相当于空间换时间了

                         

  • 相关阅读:
    关于Smartforms换页的
    数值运算及算术运算函数
    ABAP 向上取整和向下取整 CEIL & FLOOR
    webdynpro 组件重用 传值问题
    p类型最大可定义范围
    进阶:案例五: Dynamic 创建 Business Graphic
    进阶: 案例八: Drag and Drop(动态)
    进阶:案例六: Context Menu(静态 与 动态)
    进阶:案例三: Upload File using WebDynpro
    java-根据用户输入的成绩来判断等级(新手)
  • 原文地址:https://www.cnblogs.com/cl1024cl/p/6204847.html
Copyright © 2020-2023  润新知