SQL Server页中行物理存储

本文涉及的产品
RDS SQL Server Serverless,2-4RCU 50GB 3个月
推荐场景:
云数据库 RDS SQL Server,基础系列 2核4GB
简介:

SQL Server页中行物理存储

SQL Server页有很多类型:

1 – 数据页记录堆或者聚集索引叶子级的数据

2 – 索引页用于保存聚集索引中的中间页和根页,或者非聚集索引的所有页

3 – text mix page. A text page that holds small chunks of LOB values plus internal parts of text tree. These can be shared between LOB values in the same partition of an index or heap.

4 – text tree page. A text page that holds large chunks of LOB values from a single column value.

7 – sort page. A page that stores intermediate results during a sort operation.

8 – GAM page. Holds global allocation information about extents in a GAM interval (every data file is split into 4GB chunks – the number of extents that can be represented in a bitmap on a single database page). Basically whether an extent is allocated or not. GAM = Global Allocation Map. The first one is page 2 in each file. More on these in a later post.

9 – SGAM page. Holds global allocation information about extents in a GAM interval. Basically whether an extent is available for allocating mixed-pages. SGAM = Shared GAM. the first one is page 3 in each file. More on these in a later post.

10 – IAM page. Holds allocation information about which extents within a GAM interval are allocated to an index or allocation unit, in SQL Server 2000 and 2005 respectively. IAM = Index Allocation Map. More on these in a later post.

11 – PFS page. Holds allocation and free space information about pages within a PFS interval (every data file is also split into approx 64MB chunks – the number of pages that can be represented in a byte-map on a single database page. PFS = Page FreeSpace. The first one is page 1 in each file. More on these in a later post.

13 – boot page. Holds information about the database. There's only one of these in the database. It's page 9 in file 1.

15 – file header page. Holds information about the file. There's one per file and it's page 0 in the file.

16 – diff map page. Holds information about which extents in a GAM interval have changed since the last full or differential backup. The first one is page 6 in each file.

17 – ML map page. Holds information about which extents in a GAM interval have changed while in bulk-logged mode since the last backup. This is what allows you to switch to bulk-logged mode for bulk-loads and index rebuilds without worrying about breaking a backup chain. The first one is page 7 in each file.


 

PFS页= 96+4+8088+4 间隔8088, 96页头,4行头,slot0 8088 ,4slotlist
GAM/SGAM=96+4+90+4+7988+10 间隔 7988*8,96页头,4行头,90slot0,4行头,7988slot1,10slotlist
IAM页 =       96 + 4+90+4 + 7988 + 10 96页头,4行头,90slot0,4行头,7988slot1,10slotlist 

1.   数据页行存储格式

数据页的基本格式:

信息

助记符

大小(Byte

状态A

TagA

1

状态B

TagB

1

固定长度大小

Fsize

2

固定长度数据

Fdata

Fsize-4

列数量

Ncol

2

NULL位图(表中每列个位;1表示对应列为null)

Nullbits

Ceil(Ncol/8)

行中存储的可变长度列数

VarCount

2

可变长度的偏移阵列

VarOffset

2*VarCount

可变长数据

VarData

VarOffset[VarCount]-(Fsize+8-4+ Ceil(Ncol/8)+2*VarCount)

 

实例:

USE db_TestEnv

create table Index_test(id int,a varchar(10))

go

insert into Index_test select 100,'aaaaa'

go 4000

DBCC IND(db_TestEnv,Index_test,1)

DBCC PAGE(db_TestEnv,1,45969,1)

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

 

Record Type = PRIMARY_RECORD         Record Attributes =  NULL_BITMAP VARIABLE_COLUMNS

Record Size = 20                    

Memory Dump @0x613BC060

 

00000000:   30000800 64000000 02000001 00140061 †0...d..........a        

00000010:   61616161 ††††††††††††††††††††††††††††aaaa   

 

a.      第一个字节 TagA = 0x30 是由2个部分组成0x10(4个位0x20(5个位),其中0x10表示有null列,0x20表示有可变长,0x40(6个位)表示有版本标记,0x80(7个位)表示TagB是否有值。

其中1-3位为行类型分别意思如下:

        0primary record,堆上的数据页或者聚集索引的叶子页。

        1forwarded record  被转发页

        2forwarding record,转发根存页(在行移动时会出现转发页和转发根存页如行溢出,可以查看《深入解析sql server 2008 5.7.4.1 6.7.4.1的相关内容)

        3index record,聚集索引非叶子页或者非聚集索引记录

        4blob recordblob记录

        5ghost index record ,影子索引,被删除了没被清理,可以使用显示事务来观察

        6ghost data record,影子记录,被删除了没被清理,可以使用显示事务来观察

        7ghost version record,幻想记录,详细请看《深入解析 SQL Server 2008 10.7.3.8

b.      第二个字节TagB2个取值0x00,0x01.如果是0x01说明是被转发页的幻影页。若为0x01则为TagA字节的解释

其他的不需要解释了,更具上面的表格就可以。

 

2.   索引页行存储格式

索引页行存储格式分为2种:1.非叶子,2.叶子。但是会因为是堆表上的非聚集索引,还是聚集索引表上的非聚集索引有所不同。是否include对索引的存储格式没啥影响。

1.堆表下

实例:

USE db_TestEnv

create table Index_test(id INT IDENTITY,a char(10),b VARCHAR(10))

go

insert into Index_test select 'aaaaa','bbb'

go 4000

create nonclustered index ix_id_a on Index_test(id,a)

1.1  叶子页

基本格式

信息

助记符

大小(Byte

行头

Header

1

定长建值

Fkey

定长大小

表记录Rowid(fileid:page:slote)

RowID

8(4数据页,2页号,2槽号)

索引记录包含的字段个数

col

2

NULL位图(表中每列个位;1表示对应列为null)

Nullbits

Ceil(可为空列数/8)

行中存储的可变长度列数

VarCount

2

可变长度的偏移阵列

VarOffset

2*VarCount

可变长数据

VarData

VarOffset[VarCount]-(Fkey+12+ Ceil(可为空列/8)+2*VarCount)

 

DBCC PAGE(db_TestEnv,1,41006,1)

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

Record Type = INDEX_RECORD           Record Attributes =  NULL_BITMAP     Record Size = 26

Memory Dump @0x6128C060

00000000:   16220100 00616161 61612020 202020f2 †."...aaaaa     .        

00000010:   e1000001 00200003 0000†††††††††††††††..... ....  

a.      第一个字节header有以下的意义:

0x40:对于记录类型为索引记录总0

0x20: 包含可变长字段

0x10: 包含null位图数据

        1-3bit 表示是否是索引记录

         其他就不需要解释了,按照表格可以轻易的得出。

1.2  非叶子页

基本格式

信息

助记符

大小(Byte

行头

Header

1

定长建值

Fkey

定长大小

表记录Rowid(fileid:page:slote)

RowID

8(4数据页,2页号,2槽号)

下一个页所在的叶子节点(fileid:page)

KeyRowid

6(4数据页,2页号)

索引记录包含的字段个数

col

2

NULL位图(表中每列个位;1表示对应列为null)

Nullbits

Ceil(可为空列数/8)

行中存储的可变长度列数

VarCount

2

可变长度的偏移阵列

VarOffset

2*VarCount

可变长数据

VarData

VarOffset[VarCount]-(Fkey+18+ Ceil(可为空列/8)+2*VarCount)

 

DBCC PAGE(db_TestEnv,1,41007,1)

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

Record Type = INDEX_RECORD           Record Attributes =  NULL_BITMAP     Record Size = 32

Memory Dump @0x6095C060

00000000:   16010000 00616161 61612020 202020f0 †.....aaaaa     .        

00000010:   e1000001 0000007c 8d010001 00030000 †.......|........   

叶子非叶子没有什么大的区别就是非叶子少了值所在的叶子节点。需要注意的是唯一索引的非叶子比较特别没有表记录Rowid

2.在聚集索引下的非聚集索引

2.1叶子节点

信息

助记符

大小(Byte

行头

Header

1

定长建值+聚集索引定长值

Fkey

定长大小

索引记录包含的字段个数

col

2

NULL位图(表中每列个位;1表示对应列为null)

Nullbits

Ceil(可为空列数/8)

行中存储的可变长度列数

VarCount

2

可变长度的偏移阵列

VarOffset

2*VarCount

可变长数据+聚集索引变长值

VarData

VarOffset[VarCount]-(Fkey+18+ Ceil(可为空列/8)+2*VarCount)

create table Index_test(id INT IDENTITY,a varchar(10),b VARCHAR(10),iid)

go

insert into Index_test select 'aaaaa','bb'

go 4000

UPDATE dbo.Index_test SET iid = id+1

create clustered index cix_id_a on Index_test(id,a)

GO

CREATE NONCLUSTERED INDEX [idx__iid] ON [dbo].[Index_test]([iid],[b])

DBCC PAGE(db_TestEnv,1,164560,1)

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

Record Type = INDEX_RECORD           Record Attributes =  NULL_BITMAP VARIABLE_COLUMNS

Record Size = 25                    

Memory Dump @0x6083C060

00000000:   36214104 00204104 00050000 02001400 †6!A.. A.........        

00000010:   19006262 61616161 61†††††††††††††††††..bbaaaaa

这个没什么难度,第一个字节 Header 和其他的都一样就是聚集索引上的非聚集索引会带上聚集索引的key,在实例中:21410400 为自己的iid20410400id主键,6262key的键,6161616161为聚集索引key

如果聚集索引是可重复的,sql server会产生一个消除重复的数字,被当成可变长存放在可变成区域

2.2非叶子节点

 

信息

助记符

大小(Byte

行头

Header

1

定长建值+聚集索引定长值

Fkey

定长大小

下一个页所在的叶子节点(fileid:page)

KeyRowid

6(4数据页,2页号)

索引记录包含的字段个数

col

2

NULL位图(表中每列个位;1表示对应列为null)

Nullbits

Ceil(可为空列数/8)

行中存储的可变长度列数

VarCount

2

可变长度的偏移阵列

VarOffset

2*VarCount

可变长数据

VarData

VarOffset[VarCount]-(Fkey+18+ Ceil(可为空列/8)+2*VarCount)

UPDATE dbo.Index_test SET b = b+RTRIM(id重建索引

DBCC PAGE(db_TestEnv,1,177184,1)

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

Record Type = INDEX_RECORD           Record Attributes =  NULL_BITMAP VARIABLE_COLUMNS

Record Size = 32                    

Memory Dump @0x607AC060

00000000:   36020000 00010000 00e0b302 00010005 †6...............        

00000010:   00000200 1b002000 62623161 61616161 †...... .bb1aaaaa  

第一个字节和其他的都一样不解释,其他的按表格都可以解析

如果聚集索引是可重复的,sql server会产生一个消除重复的数字,被当成可变长存放在可变成区域

 

3.聚集索引中

在聚集索引下只有非叶子页才是索引页

基本格式

信息

助记符

大小(Byte

行头

Header

1

下层最小固定聚集索引建值

Fkey

固定聚集索引建大小

一下层页号(fileid:page)

KeyRowid

6(4数据页,2页号)

索引记录包含的字段个数

col

2

NULL位图(表中每列个位;1表示对应列为null)

Nullbits

Ceil(可为空列数/8)

行中存储的可变长度列数

VarCount

2

可变长度的偏移阵列

VarOffset

2*VarCount

可变长数据

VarData

VarOffset[VarCount]-(Fkey+18+ Ceil(可为空列/8)+2*VarCount)

实例:

create table Index_test(id INT IDENTITY,a varchar(10),b VARCHAR(10))

go

insert into Index_test select 'aaaaa','bb'

go 4000

create clustered index cix_id_a on Index_test(id,a)

GO

DBCC IND(db_TestEnv,Index_test,1)

DBCC PAGE(db_TestEnv,1,51106,1)

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

Record Type = INDEX_RECORD           Record Attributes =  NULL_BITMAP VARIABLE_COLUMNS

Record Size = 23                    

Memory Dump @0x6056C060

00000000:   36010000 0097b300 00010002 00000100 †6...............        

00000010:   17006161 616161††††††††††††††††††††††..aaaaa 

A.     第一个字节header和其他的一样

0x40:对于记录类型为索引记录总0

0x20: 包含可变长字段

0x10: 包含null位图数据

        1-3bit 表示是否是索引记录

         其他的表格中说明很详细。





    本文转自 Fanr_Zh 博客园博客,原文链接:http://www.cnblogs.com/Amaranthus/archive/2013/01/31/2886581.html,如需转载请自行联系原作者



相关实践学习
使用SQL语句管理索引
本次实验主要介绍如何在RDS-SQLServer数据库中,使用SQL语句管理索引。
SQL Server on Linux入门教程
SQL Server数据库一直只提供Windows下的版本。2016年微软宣布推出可运行在Linux系统下的SQL Server数据库,该版本目前还是早期预览版本。本课程主要介绍SQLServer On Linux的基本知识。 相关的阿里云产品:云数据库RDS SQL Server版 RDS SQL Server不仅拥有高可用架构和任意时间点的数据恢复功能,强力支撑各种企业应用,同时也包含了微软的License费用,减少额外支出。 了解产品详情: https://www.aliyun.com/product/rds/sqlserver
相关文章
|
5月前
|
SQL IDE Java
Java连接SQL Server数据库的详细操作流程
Java连接SQL Server数据库的详细操作流程
|
2月前
|
关系型数据库 MySQL 网络安全
5-10Can't connect to MySQL server on 'sh-cynosl-grp-fcs50xoa.sql.tencentcdb.com' (110)")
5-10Can't connect to MySQL server on 'sh-cynosl-grp-fcs50xoa.sql.tencentcdb.com' (110)")
|
4月前
|
SQL 存储 监控
SQL Server的并行实施如何优化?
【7月更文挑战第23天】SQL Server的并行实施如何优化?
115 13
|
4月前
|
SQL
解锁 SQL Server 2022的时间序列数据功能
【7月更文挑战第14天】要解锁SQL Server 2022的时间序列数据功能,可使用`generate_series`函数生成整数序列,例如:`SELECT value FROM generate_series(1, 10)。此外,`date_bucket`函数能按指定间隔(如周)对日期时间值分组,这些工具结合窗口函数和其他时间日期函数,能高效处理和分析时间序列数据。更多信息请参考官方文档和技术资料。
|
4月前
|
SQL 存储 网络安全
关系数据库SQLserver 安装 SQL Server
【7月更文挑战第26天】
61 6
|
4月前
|
存储 SQL C++
对比 SQL Server中的VARCHAR(max) 与VARCHAR(n) 数据类型
【7月更文挑战7天】SQL Server 中的 VARCHAR(max) vs VARCHAR(n): - VARCHAR(n) 存储最多 n 个字符(1-8000),适合短文本。 - VARCHAR(max) 可存储约 21 亿个字符,适合大量文本。 - VARCHAR(n) 在处理小数据时性能更好,空间固定。 - VARCHAR(max) 对于大文本更合适,但可能影响性能。 - 选择取决于数据长度预期和业务需求。
386 1
|
3月前
|
SQL 安全 Java
驱动程序无法通过使用安全套接字层(SSL)加密与 SQL Server 建立安全连接。错误:“The server selected protocol version TLS10 is not accepted by client
驱动程序无法通过使用安全套接字层(SSL)加密与 SQL Server 建立安全连接。错误:“The server selected protocol version TLS10 is not accepted by client
483 0
|
4月前
|
SQL Oracle 关系型数据库
MySQL、SQL Server和Oracle数据库安装部署教程
数据库的安装部署教程因不同的数据库管理系统(DBMS)而异,以下将以MySQL、SQL Server和Oracle为例,分别概述其安装部署的基本步骤。请注意,由于软件版本和操作系统的不同,具体步骤可能会有所变化。
310 3
|
4月前
|
SQL 存储 安全
数据库数据恢复—SQL Server数据库出现逻辑错误的数据恢复案例
SQL Server数据库数据恢复环境: 某品牌服务器存储中有两组raid5磁盘阵列。操作系统层面跑着SQL Server数据库,SQL Server数据库存放在D盘分区中。 SQL Server数据库故障: 存放SQL Server数据库的D盘分区容量不足,管理员在E盘中生成了一个.ndf的文件并且将数据库路径指向E盘继续使用。数据库继续运行一段时间后出现故障并报错,连接失效,SqlServer数据库无法附加查询。管理员多次尝试恢复数据库数据但是没有成功。
|
4月前
|
SQL 存储 关系型数据库
关系型数据库SQL Server学习
【7月更文挑战第4天】
80 2
下一篇
无影云桌面