NULL与“”的存储空间

NULL与“”的存储空间

引子

部门例会,讨论起数据库的NULL和“” 是否相同,本人真心认为不同,但对于报表把NULL显示成“”来说,又只能是一样的。矛盾:(

 

但对于一个可空的字段,取值NULL和“”空间占用是否相同,这个必须深入数据库存储来看才能深刻知道 (如果没有特殊说明,数据库指的是SQLServer) 。

 

分析

首先建立一个临时表

CREATE TABLEA(

a INTNOTNULL,

b CHAR(8)NULL,

c nvarchar(200)NULL,

d NVARCHAR(200)NULL

)

INSERT A(a,b,c,d)VALUES(0xcccccccc,NULL,NULL,'CC')

INSERT A(a,b,c,d)VALUES(0xdddddddd,'','','DD')

 

 

通过执行

dbcctraceon(3604)

dbccind('tempdb','A',-1)

可以得到如下:

 

有了1:150 有可以通过如下语句

dbccpage('tempdb',1,150,1)

 得到记录的二进制存储结构

 

 

PAGE: (1:150)

 

 

BUFFER:

 

 

BUF @0x00000008620D2DC0

 

bpage = 0x000000071D940000          bhash = 0x0000000000000000          bpageno = (1:150)

bdbid = 2                           breferences = 0                     bcputicks = 0

bsampleCount = 0                    bUse1 = 47930                       bstat = 0x10b

blog = 0xab215acc                   bnext = 0x0000000000000000         

 

PAGE HEADER:

 

 

Page @0x000000071D940000

 

m_pageId = (1:150)                  m_headerVersion = 1                 m_type = 1

m_typeFlagBits = 0x0                m_level = 0                         m_flagBits = 0x8000

m_objId (AllocUnitId.idObj) = 5084  m_indexId (AllocUnitId.idInd) = 2304

Metadata: AllocUnitId = 648518346674536448                              

Metadata: PartitionId = 648518346670145536                               Metadata: IndexId = 0

Metadata: ObjectId = 325576198      m_prevPage = (0:0)                  m_nextPage = (0:0)

pminlen = 16                        m_slotCnt = 2                       m_freeCnt = 8034

m_freeData = 154                    m_reservedCnt = 0                   m_lsn = (34:1940:35)

m_xactReserved = 0                  m_xdesId = (0:0)                    m_ghostRecCnt = 0

m_tornBits = 0                      DB Frag ID = 1                     

 

Allocation Status

 

GAM (1:2) = ALLOCATED               SGAM (1:3) = ALLOCATED             

PFS (1:1) = 0x61 MIXED_EXT ALLOCATED  50_PCT_FULL                        DIFF (1:6) = CHANGED

ML (1:7) = NOT MIN_LOGGED          

 

DATA:

 

 

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

 

Record Type = PRIMARY_RECORD        Record Attributes =  NULL_BITMAP VARIABLE_COLUMNS

Record Size = 29                   

Memory Dump @0x000000003881A060

 

0000000000000000:   30001000 cccccccc 00000000 00000000 04000602  0...................

0000000000000014:   0019001d 00430043 00                          .....C.C.

 

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

 

Record Type = PRIMARY_RECORD        Record Attributes =  NULL_BITMAP VARIABLE_COLUMNS

Record Size = 29                   

Memory Dump @0x000000003881A07D

 

0000000000000000:   30001000 dddddddd 20202020 20202020 04000002  0.......        ....

0000000000000014:   0019001d 00440044 00                          .....D.D.

 

OFFSET TABLE:

 

Row - Offset                       

1 (0x1) - 125 (0x7d)               

0 (0x0) - 96 (0x60)                

 

 

DBCC 执行完毕。如果 DBCC 输出了错误信息,请与系统管理员联系。

 

 

看到这只能翻开书继续


首先一个SQLServer数据库页的结构如下:


数据行里每一条记录的格式如下:

 

通过上面信息,分析数据如下:


蓝1,蓝2: 状态位

蓝3:列数偏移 0010 指向 蓝6的位置

蓝4:a字段的内容

蓝5:b字段空间, 蓝7 0000110  (第二列和第三列为空)

蓝6:列个数 0004  (4列)

蓝7: NULL的位掩图

蓝8:可变列数

蓝9:第一个可变结束位置 (0019)25

蓝10:第二个可变结束位置 (001d) 29

蓝11:  43004300   (d字段内容为“CC”)

 

 

红1,红2: 状态位

红3:列数偏移 0010 指向 红6的位置

红4:a字段的内容

红5:b字段空间

红6:列个数 0004  (4列)

红7: NULL位掩图 0000110  (第二列和第三列为空)

红8:可变列数

红9:第一个可变结束位置 (0019)25

红10:第二个可变结束位置 (001d) 29

红11:  43004300   (d字段内容为“DD”)

 

红5和蓝5 内容不一样,但空间一样(可空固定长度的b字段)

红9和蓝9 内容一样,但红7和蓝7:的NULL位掩图不一样(可空非固定长度的c字段)

 

结论

 

对于一个可空字段来说,SQLServer的NULL和“”所占用空间是一样的。

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值