数据库之数据行结构(SQL Server )

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/sinat_41104353/article/details/83033665

感觉关于数据库的 数据行结构 (data row/record structure) 这方面的内容国内的资料特别少,老师上课讲到后,怎么搜也搜不到,最后还是爬梯|=|子才搜到一些的(国内真的惨),这里对老师上课讲的和网上看的做一个小总结,加深印象。

数据行结构

行结构总览

SQL Server系统 数据类型可以在逻辑上分为两个不同的组,例如固定长度(fixed-length)和可变长度(variable-length)类型。 固定长度数据类型(如int,datetime,char等)始终使用相同的存储空间,无论值是什么,即使它是NULL。 例如,int列始终使用4个字节,nchar(10)列始终使用20个字节来存储信息。

相反,可变长度数据类型(例如varchar,varbinary和其他一些数据类型)使用尽可能多的存储空间来存储数据加上两个额外字节。 例如,nvarchar(4000)列将仅使用12个字节来存储5个字符的字符串,并且在大多数情况下,2个字节用于存储NULL值。 我们将讨论可变长度列以后不为NULL值使用存储空间的情况。

下面是两张关于 SQL Server 里数据行结构的图,其中一张来自http://aboutsqlserver.com/2013/10/15/sql-server-storage-engine-data-pages-and-data-rows/
在这里插入图片描述
在这里插入图片描述

该行的前2个字节(称为状态位A(Status Bits A)和状态位B(Status Bits B))是包含有关该行的信息的位图,例如行类型是什么; 该行是否已被逻辑删除(幽灵(ghosted)); 该行是否具有NULL值,可变长度列和版本控制标记。

行中接下来的两个字节用于存储数据的固定长度(fixed-length)部分的长度。 它们之后是固定长度的数据(fixed-length data)。

在固定长度数据部分之后,存在空位图(null bitmap),其包括两个不同的数据元素。 第一个2字节元素是行中的列数(number of columns)。 接下来是空位图数组(null bitmap array),该数组使用一位来表示表中的每一列,无论它是否可为空。
ps. 原文中的 它 有点不明白代指什么。因为使用一位来表示一列,所以共有 Ceiling(#cols / 8) 个字节

即使表没有可空列,空位图也始终存在于堆表或聚簇索引叶行的数据行中。但是,当索引中没有可为空的列时,非页索引行中的空位图不存在,也不存在非聚簇索引的叶级行。

在空位图之后,是该行的可变长度数据(variable-length data)部分。 它从行中的两个字节数量的可变长度列(variable-length columns)开始,后跟可变长度列偏移数组(variable-length column offset array)。 即使值为空,SQL Server 也会为每行中的每个可变长度列存储两个字节的偏移值。它后跟数据的实际可变长度部分。(它 指 可变长度列偏移数组)

扫描二维码关注公众号,回复: 3563550 查看本文章

最后,在行的末尾有可选的14字节版本控制标记。 该标记在操作期间使用,这需要行版本控制,例如联机索引重建,乐观隔离级别等。

行结构补充

在这里插入图片描述

至于 Status Bits A 的 8位 有更具体的定义:

含义
Bit 0 Versioning information. In SQL server 2008 this is always 0
Bits 1 to 3 This is three bit value define the record type.
0 data record.
1 Forwarded record. (转向记录)
2 a forwarding stub. (转向存根)
3 Index record.
4 blob fragment or row overflow data.
5 ghost index record. (幽灵索引记录)
6 ghost data record (幽灵数据记录)
7 ghost version record
Bit 4 Null bitmap exists or not.In SQL server 2008 null bitmap exists even if there is no null able columns
Bit 5 Indicate variable column exists or not.
Bit 6 Indicate that row contain versioning information
Bit 7 Not used in SQL server

对于 Status Bits B

Only one bit is used in this to indicate that the record is ghost forwarded record.

实例

例一 详

此例来自 http://aboutsqlserver.com/2013/10/15/sql-server-storage-engine-data-pages-and-data-rows/
首先,让我们创建表,用一些数据填充它并查看实际的行数据。

use tempdb
go

create table dbo.DataRows
(
    ID int not null,
    Col1 varchar(255) null,
    Col2 varchar(255) null,
    Col3 varchar(255) null
);

insert into dbo.DataRows(ID, Col1, Col3)  values (1,replicate('a',255),replicate('c',255));
insert into dbo.DataRows(ID, Col2) values (2,replicate('b',255));

dbcc ind
(
    'tempdb' -- Database name
    ,'dbo.DataRows' -- Table Name
    ,-1 -- Display info about all pages from the table
);

没有文档但很出名的 DBCC IND 命令返回有关表页分配的信息。
Page Allocation (DBCC IND results)

有两个属于该表的页面。第一个 PageType = 10 是名为 IAM 分配映射页面的特殊类型。此页面跟踪属于特定对象的页面。我们现在不关注它 - 我们将在以后博客文章中介绍分配映射页面(allocation map pages)。(这个要去看原作者的博文了)

PageType = 1 的页面是包含数据行的实际数据页面。 PageFID 和 PagePID 列显示页面的实际文件和页码。 你可以使用另一个没有文档的命令 DBCC PAGE 来检查其内容

-- Redirecting DBCC PAGE output to console rather than error log
dbcc traceon(3604);
dbcc page
(
    'tempdb' -- Database name
    ,1 -- File ID
    ,214643 -- Page ID
    ,3 -- Output mode: 3 - display page header and row details
);

你可以看到 DBCC PAGE 的输出,该输出对应于下面的第一个数据行。 SQL Server 以字节交换顺序存储数据。 例如,两字节值 0001 将存储为 0100。(叨叨一嘴,是大小端模式?)

Slot 0 Offset 0x60 Length 39
Record Type = PRIMARY_RECORD        Record Attributes =  NULL_BITMAP VARIABLE_COLUMNS
Record Size = 39                    
Memory Dump @0x000000000EABA060

0000000000000000:30000800 01000000 04000403 001d001d 00270061 0................'.a
0000000000000014:61616161 61616161 61636363 63636363 636363   aaaaaaaaacccccccccc

Slot 0 Column 1 Offset 0x4 Length 4 Length (physical) 4
ID = 1                              

Slot 0 Column 2 Offset 0x13 Length 10 Length (physical) 10
Col1 = aaaaaaaaaa                   

Slot 0 Column 3 Offset 0x0 Length 0 Length (physical) 0
Col2 = [NULL]                       

Slot 0 Column 4 Offset 0x1d Length 10 Length (physical) 10
Col3 = cccccccccc

我们来看看数据行结构:
Row Structure with the data (Row 1)
如你所见,该行以两个状态位字节开始,后跟两个字节的值 0800。这是字节 0008 的交换值,它是行中列数属性的偏移量。 此偏移量告诉 SQL Server 行的固定长度数据部分(fixed-length data part)在哪里结束。

接下来的四个字节用于存储固定长度的数据,在我们的例子中是 ID 列。 之后,有两个字节的值表明数据行有四列,后跟一个字节的 NULL 位图。 位图中只有四列一个字节就足够了。 它以二进制格式存储 04 的值 00000100。 它表示该行中的第三列包含 NULL 值。

接下来的两个字节存储行中可变长度列的数量,即 3(按字节交换顺序为 0300)。 它由偏移数组跟随,其每两个字节存储可变长度列数据结束地方的偏移量。 如你所见,即使 Col2 为 NULL,它仍然使用 offset-array 中的槽(slot)。 最后,是来自可变长度列的实际数据。

ps. 还有个命令 dbcc traceon(3604) 大家可以了解下。

例二 略

在这里插入图片描述
在这里插入图片描述

参考资料

http://aboutsqlserver.com/2013/10/15/sql-server-storage-engine-data-pages-and-data-rows/
http://www.sqlservercentral.com/blogs/practicalsqldba/2012/08/22/sql-serverunderstanding-the-data-record-structure/
这两篇可以再去看看,我没摘全。

发完博客在相关文章里看到有一篇也是介绍 数据行结构 的:
https://blog.csdn.net/yangmeng518889/article/details/53911358

猜你喜欢

转载自blog.csdn.net/sinat_41104353/article/details/83033665