--建立测试表
create table t_test
(
col1 int,
col2 varchar(10),
col3 datetime,
col4 char(10),
col5 nvarchar(4)
)
go
--插入数据
insert t_test values(1,'ABC','2010-03-15','123',N'abc')
insert t_test values(2,'DEF',CURRENT_TIMESTAMP,'4567',N'defg')
go
--查看数据页
DBCC TRACEON (3604,-1)
DBCC IND([TEST], 't_test', -1)
DBCC PAGE([TEST], 1, 693,3)
DBCC TRACEOFF (3604,-1)
GO
/*
Slot 0 Offset 0x60 Length 44
Record Type = PRIMARY_RECORD Record Attributes = NULL_BITMAP VARIABLE_COLUMNS
Record Size = 44
Memory Dump @0x5FF1C060
00000000: 30001a00 01000000 00000000 3a9d0000 †...........:...
00000010: 31323320 20202020 20200500 00020026 †23 .....&
00000020: 002c0041 42436100 62006300 † ?† ?† ?† ?† ?.,.ABCa.b.c.
*/
--记录长度
Select 1+1+2+(4+8+10)+2+CEILING(5/8.0)+2+2*2+(3+6)
/*
内容解析
状态位A:30->00110000 它是一个行属性的位图从高位存到地位(右边第一位是bit0)
bit0:版本信息,SQL2005/08总是为
bit1-3: 0=(primary record);1=(forwarded record);2=(forwarding stud);3=(index record);4=(溢出数据);5=(ghost索引记录);6=(ghost数据记录)
bit4:表示存在NULL位图(在数据行里SQL2005/08总存在NULL位图)
bit5:表示存在变长列
bit6:未启用
bit7:表示存在幽灵记录
回到我们的例子中,我们的bit4为bit5为表示存在NULL位图及存在变长列
状态位B:00->未启用
列数的出现位置:1a00->00000000 00011010=26<就是出现的位置>
定长数据部分(col1,col3,col4)
Col1 4字节 01000000
Col3 8字节 00000000 3a9d0000
Col4 10字节31323320 20202020 2020
列总数0500->00000000 00000101=5 表示该表有列
NULL位图:00->00000000 因为该表只有列所以只需要看后面个,0表示该行的对应列不为NULL
变长列的数目:0200->00000000 00000010=2 表示该表有列(col2,col5)
第一变长列数据终止位置:2600->00000000 00100110=38
第二变长列数据终止位置:2c00->00000000 00101100=44
第一列变长列的数据:41 4243->01000001 01000010 01000011='ABC'
第二列变长列的数据:6100 6200 6300->01100001 00..00 01100010 00..00 01100011 00..00='abc' 这里用六个字节是因为它是NVARCHAR类型2个字节才能存一个字符
*/
