您的位置:首页 > 数据库

sqlserver 大字段存储格式(一)

2017-03-03 11:20 330 查看


数据页

 数据页是包含已经被添加到某个数据库表中的用户数据的结构,SQLServer有3种数据页面,每个页面都以一种不同的格式存储数据。分别是用于行内数据、行溢出数据和LOB数据的页面。
 和其他类型的页面一样,数据页面具有8KB的固定长度,它们主要由3个主要部分组成,页眉、数据行和行偏移数组



页眉

每个数据页前96个字节是页眉。



行内数据的数据行
 页眉下面是表的真实数据行的存储区域。单个数据行的最大容量是8060字节的行内数据。行也可能有行溢出和存储在独立页上的lob数据。
行偏移阵列
 行偏移阵列是一块2字节的条目,其中每个目录都是表示相应数据行起始页的偏移量。每一行在这个阵列中都有一个2字节条目。


行溢出数据:

 超出8060字节大小限制的一种存储方式是使用变长列,因为对于变长数据来说,SQLServer可以在特殊的行溢出页中存储这些列,只要所有长度固定的列适合标准行内大小的限制。可以存在overflow页上的数据类型包括varbinary、varchar、nvarchar和sqlvariant列。
创建最大定义长度大于8060字节的一张表:

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查看页面情况:

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
然后用DBCCPAGE查看2189页上面的数据,使用dbccPAGE前必须先执行:

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指针,结构如下:



下面是fn_dblog显示的这个事务的结果,其中第5条的[RowLog
Contents 0]记录了上面一页的信息:

0x30000400040000040045085D889110C51865…6565020000000100000047150000340800009F0800000100000067676767…7676868686868…68
可以看到中间也是包含24字节指针

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息