《Pro SQL Server Internals,Second Edition》第八周翻译

第一章■数据内部存储

 

《Pro SQL Server Internals,Second Edition》第八周翻译_第1张图片

图1-5.检查是否启用即时文件初始化-SQL Server错误日志

控制数据库文件大小的另一个重要数据库选项是自动收缩。当此选项为启用后,SQL Server每30分钟删除一次数据库文件,减小其大小并释放空间到操作系统。此操作占用大量资源,很少有用,因为数据库文件当新数据进入系统时再次增长。此外,它还大大增加了  数据库容量。不应启用自动删除。此外,微软将删除此选项SQL Server的版本。

■注:我们将在第6章“索引碎片”中更详细地讨论索引碎片。

数据页和数据行 

数据库中的空间分为逻辑8KB页。这些页面从开始连续编号如果为零,则可以通过指定文件ID和页码来引用它们。页码是始终是连续的,这样当SQL Server增长数据库文件时,新页将从开始编号从文件中的最高页码加上一个。同样,当SQL Server删除文件时,它会删除              文件最大的页数。

SQL Server中的数据存储

一般来说,SQL Server存储和使用数据库中的数据。使用传统的基于行的存储,数据存储在数据行中。将所有列中的数据组合在一起。             

SQL Server 2012引入了列存储索引和基于列的存储。这个技术商店每列而不是每行的数据。我们将在第七部分介绍基于列的存储这本书。              

最后,SQL Server 2014引入了一组内存技术,并进一步改进了这些技术在SQL Server 2016中。即使它们为了冗余而将数据保存在磁盘上,它们的存储格式与基于行和列的存储非常不同。我们将在记忆中讨论本书第八部分的技术。本书的这一部分主要讨论基于行的存储和经典的B树索引和堆。  

图1-6显示了数据页的结构

《Pro SQL Server Internals,Second Edition》第八周翻译_第2张图片

图1-6数据页结构

96字节的页标题包含有关页的各种信息,例如该页所属、行数和页上可用空间量、指向上一页的链接如果页在索引页链中,则为下一页,依此类推。页面标题后面是存储实际数据的区域。接下来是自由空间。最后有一个插槽数组,它是由两个字节的条目组成的块,指示相应数据的偏移量行从页面开始。插槽数组指示页上数据行的逻辑顺序。如果页面上的数据需要按照索引键的顺序排序,SQL Server不会对页面上的数据行进行物理排序,而是它根据索引排序顺序填充槽数组。插槽0(图1-6中最右边)存储偏移量页上具有最低键值的数据行;槽1,第二个最低键值;等等。我们将在下一章中更深入地讨论索引。 SQL Server提供了一组丰富的系统数据类型,可以在逻辑上分为两种不同的类型组:固定长度和可变长度。固定长度的数据类型,如int、datetime、char等,始终使用相同数量的存储空间,不管它们的值如何,即使它是空的。例如,int列总是使用4个字节,nchar(10)列总是使用20个字节来存储信息。相比之下,可变长度的数据类型(如varchar、varbinary和其他一些类型)使用的次数也一样多。存储数据所需的存储空间,加上两个额外的字节。例如,nvarchar(4000)列只使用12个字节来存储5个字符的字符串,在大多数情况下,使用2个字节来存储空值。稍后我们将讨论这一章变长列不使用存储空间存储空值的情况。              

让我们看看数据行的结构,如图1-7所示。

《Pro SQL Server Internals,Second Edition》第八周翻译_第3张图片

 

图1-7。数据行结构

行的前两个字节称为状态位A和状态位B,是包含信息的位图。关于行,例如行类型、行是否已被逻辑删除(重影)以及行是否为空值、可变长度列和版本控制标记。行中接下来的两个字节用于存储数据固定长度部分的长度。他们后面是固定长度的数据本身。 在固定长度的数据部分之后,有一个空位图,其中包含两个不同的数据元素。 前两个字节元素是行中的列数。第二个是空位图数组。这个数组无论表的每列是否可以为空,都使用一位。空位图总是出现在堆表或聚集索引叶行的数据行中,即使在表没有可以为空的列。但是,空位图不存在于非叶索引行中,也不存在于当索引中没有可为空的列时,非聚集索引的叶级行。在空位图之后,是行的可变长度数据部分。它以两个字节开头 行中可变长度列的数目,后跟列偏移量数组。SQL Server为行中的每个可变长度列存储两个字节的偏移量值,即使该值为空。后面是数据的实际可变长度部分。最后,在末尾有一个可选的14字节版本控制标记排成一行。此标记用于需要行版本控制的操作,例如联机索引重建,最佳的隔离水平、触发因素和其他一些因素。

■注:我们将在第6章中讨论索引维护、第9章中的触发器以及高级隔离级别在第21章  

让我们创建一个表,用一些数据填充它,并查看实际的行数据。代码显示在清单1-4。replicate函数将作为第一个参数提供的字符重复十次。

清单1-4。数据行格式:表格创建

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',10),replicate('c',10));

insert into dbo.DataRows(ID, Col2) values (2,replicate('b',10));

dbcc ind

(

'SQLServerInternals' /*Database Name*/

,'dbo.DataRows' /*Table Name*/

,-1 /*Display information for all pages of all indexes*/

);

虽然未记录但dbcc ind命令返回有关表页的信息分配众所周知的。您可以在图1-8中看到这个命令的输出

图1-8。数据库输出

有两页属于该表。第一个页面类型为10的页面是一种特殊的页面类型。 称为IAM分配图。此页跟踪属于特定对象的页。不要专注于不过,现在我们将在本章后面介绍分配图页面。

 

注意:SQL Server 2012引入了另一个未记录的数据管理功能(DMF),sys.dm_db_ 数据库页面分配,可用于替换dbcc ind命令。产量与DBCC IND相比,此DMF提供了更多的信息,并且可以与其他系统DMV结合使用和/或目录视图。

pageType=1的页面是包含数据行的实际数据页。PageFID和pagepid列显示页面的实际文件和页码。你可以用另一个没有证件的命令dbcc page检查其内容,如清单1-5所示。

清单1-5。数据行格式:dbcc页面返回

-- Redirecting DBCC PAGE output to console

dbcc traceon(3604);

dbcc page

(

'SqlServerInternals' /*Database Name*/

,1 /*File ID*/

,214643 /*Page ID*/

,3 /*Output mode: 3 - display page header and row details */

);

清单1-6显示了对应于第一个数据行的DBCC页的输出。SQL Server存储按字节交换顺序的数据。例如,两个字节的值0001将存储为0100。

第一章■数据存储内部 

清单1-6。第一行的DBCC页输出

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

让我们更详细地查看数据行,如图1-9所示。

《Pro SQL Server Internals,Second Edition》第八周翻译_第4张图片

图1-9。第一数据行

如您所见,行以两个状态位开头,后跟一个双字节值0800。这就是字节交换值0008,这是行中“列数”属性的偏移量。此偏移量告诉SQL Server行的固定长度数据部分的结束位置。 接下来的四个字节用于存储固定长度的数据,在我们的例子中是id列。之后,  有两个字节的值表示数据行有四列,后跟一个一字节的空值位图。只需四列,位图中的一个字节就足够了。存储值04,即00000100二进制格式。它指示行中的第三列包含空值。 接下来的两个字节存储行中可变长度列的数量,即3(按字节wapped顺序为0300)。后面是一个偏移数组,其中每两个字节存储可变长度列数据结束处的偏移量。如您所见,即使col2为空,它仍然使用偏移数组中的槽。最后,还有来自可变长度列的实际数据。 现在,让我们看看第二个数据行。清单1-7显示了DBCC页面输出,图1-10显示了  行数据。

《Pro SQL Server Internals,Second Edition》第八周翻译_第5张图片

图1-10。第二数据行数据

清单1-7。第二行的DBCC页输出

Slot 1 Offset 0x87 Length 27

Record Type = PRIMARY_RECORD Record Attributes = NULL_BITMAP VARIABLE_COLUMNS

Record Size = 27

Memory Dump @0x000000000EABA087

0000000000000000: 30000800 02000000 04000a02 0011001b 00626262 0................bbb

0000000000000014: 62626262 626262 bbbbbbb

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

ID = 2

Slot 1 Column 2 Offset 0x0 Length 0 Length (physical) 0

Col1 = [NULL]

Slot 1 Column 3 Offset 0x11 Length 10 Length (physical) 10

Col2 = bbbbbbbbbb

Slot 1 Column 4 Offset 0x0 Length 0 Length (physical) 0

Col3 = [NULL]

第二行中的空位图表示一个二进制值000001010,它显示第1列和3列为空。尽管该表有三个可变长度的列,但可变长度的数目行中的列表示偏移数组中只有两个列/槽。SQL Server没有维护行中有关尾随的空变长列的信息。

■提示:通过以可变长度的方式创建表,可以减小数据行的大小。通常存储空值的列被定义为CREATETABLE语句中的最后一列。这是唯一一种是CREATETABLE语句中的列顺序很重要的情况。

固定长度的数据和内部属性必须适合单个数据页上可用的8060字节当情况并非如此时,SQL Server不允许您创建表。例如,清单1-8中的代码产生错误。

第一章■数据存储内部

清单1-8。创建数据行大小超过8060字节的表

create table dbo.BadTable

(

Col1 char(4000),

Col2 char(4060)

)

消息1701,级别16,状态1,行1创建或更改表“baddable”失败,因为最小行大小为8067,包括7字节的内部开销。这超过了允许的最大表行大小8060字节。

容量对象存储

即使固定长度的数据和行的内部属性必须适合单个页面,SQL Server可以将可变长度的数据存储在不同的数据页上。存储数据有两种不同的方法,取决于数据类型和长度。

行溢出存储

SQL Server在调用的特殊页上存储长度不超过8000字节的可变列数据行溢出页。让我们创建一个表,并用清单1-9中所示的数据填充它。

1-9。行溢出数据:创建表

create table dbo.RowOverflow

(

ID int not null,

Col1 varchar(8000) null,

Col2 varchar(8000) null

);

insert into dbo.RowOverflow(ID, Col1, Col2) values

(1,replicate('a',8000),replicate('b',8000));

如您所见,SQL Server创建表并插入数据行,但没有任何错误,即使数据行大小超过8060字节。让我们使用dbcc ind命令查看表页分配。这个结果如图1-11所示。

图1-11。行溢出数据:DBCC IND结果

原著信息:

此篇文章翻译自《Pro SQL Server Internals, 2nd edition》的CHAPTER 1 Data Storage Internals中的Data Pages and Data Rows一节。

原著:《Pro SQL Server Internals, 2nd edition》    原文作者:Dmitri Korotkevitch

你可能感兴趣的:(作业)