数据页是包含已经被添加到某个数据库表中的用户数据的结构,SQLServer有3种数据页面,每个页面都以一种不同的格式存储数据。分别是用于行内数据、行溢出数据和LOB数据的页面。
和其他类型的页面一样,数据页面具有8KB的固定长度,它们主要由3个主要部分组成,页眉、数据行和行偏移数组
每个数据页前96个字节是页眉。
页眉下面是表的真实数据行的存储区域。单个数据行的最大容量是8060字节的行内数据。行也可能有行溢出和存储在独立页上的lob数据。
行偏移阵列是一块2字节的条目,其中每个目录都是表示相应数据行起始页的偏移量。每一行在这个阵列中都有一个2字节条目。
超出8060字节大小限制的一种存储方式是使用变长列,因为对于变长数据来说,SQLServer可以在特殊的行溢出页中存储这些列,只要所有长度固定的列适合标准行内大小的限制。可以存在overflow页上的数据类型包括varbinary、varchar、nvarchar和sqlvariant列。
create table dbo.bigrows
(a varchar(3000),
b varchar(3000),
c varchar(3000),
d varchar(3000)
);
insert into bigrows selectreplicate('e',2100),
replicate('f',2100),replicate('g',2100),
replicate('h',2100);
select object_name(object_id) as name,
partition_id, partition_number aspnum, rows,
allocation_unit_id as au_id, type_descas page_type_desc,
total_pages as pages
from sys.partitions p joinsys.allocation_units a
on p.partition_id = a.container_id
whereobject_id=OBJECT_ID('dbo.bigrows')
结果:有两页用于存储标准行内数据的一行,两页用于存储行溢出数据的一行
dbcc ind (Simple, bigrows, -1)
pagetype:
--1数据页
--2索引页
--3 LOB或行溢出页, text_mixed
--4 LOB或行溢出,text_data
--8 GAM page
--9 sgam page
--10 IAM页面
--11 pfs page
DBCC TRACEON (3604);
dbcc page ('Simple',1,2189,3)
前面的一些内容就不看了,看一下这一页上面存储的数据内容(中间...省略了重复内容)
0000000000000000: 3000040004000004 0045085d 889110c5 18656565 0........E.].....eee
0000000000000014: 6565656565656565 65656565 65656565 65656565 eeeeeeeeeeeeeeeeeeee
... ...
0000000000000820: 6565656565656565 65656565 65656565 65656565 eeeeeeeeeeeeeeeeeeee
0000000000000834: 6565656565656565 65656565 65656565 65020000 eeeeeeeeeeeeeeeee...
0000000000000848: 0001000000471500 00340800 009f0800 00010000 .....G...4..........
000000000000085C: 0067676767676767 67676767 67676767 67676767 .ggggggggggggggggggg
0000000000000870: 6767676767676767 67676767 67676767 67676767 gggggggggggggggggggg
... ...
0000000000001068: 67676767 6767676767676767 67676767 67676767 gggggggggggggggggggg
000000000000107C: 6767676767676767 67676767 67676767 67676767 gggggggggggggggggggg
0000000000001090: 67686868 68686868 68686868 68686868 68686868 ghhhhhhhhhhhhhhhhhhh
... ...
0000000000001874: 6868686868686868 68686868 68686868 68686868 hhhhhhhhhhhhhhhhhhhh
0000000000001888: 6868686868686868 68686868 68686868 68686868 hhhhhhhhhhhhhhhhhhhh
000000000000189C: 6868686868686868 68686868 68686868 68686868 hhhhhhhhhhhhhhhhhhhh
00000000000018B0: 6868686868686868 68686868 68686868 68686868 hhhhhhhhhhhhhhhhhhhh
00000000000018C4: 68 h
这一页上面存储了我们前面插入的一行数据,可以看到a,c,d列都在这里面直接存储的,而b列却找不到;b列就是我们这边要找的overflow列,上面结果中红色部分是24个字节的overflow指针,结构如下:
0x30000400040000040045085D889110C51865…6565020000000100000047150000340800009F0800000100000067676767…7676868686868…68
可以看到中间也是包含24字节指针