简单说来,表就是一个关于特定实体(人、地点或事物)的数据集合。这种实体有一些命名属性(名称、数量或类型等),在表中以命名列的形式来表现。表中的每个数据实例表现为单个实体,或者叫行(正式名称为元组)。
表的内部存储结构
数据页面
数据页面是一种结构,它包含已经被添加到数据库表中的用户数据。数据页面分为三种不同类型,每一种用于存储不同格式的数据,分别是行内数据、行溢出数据及LOB数据。
与SQL Server中其他类型的页面一样,数据页面的大小固定为8 KB(8 192字节)。数据页面由三个主要部分组成:页面报头、数据行及行偏移矩阵。
页面报头
包括当前数据页所属文件号及其页面编号,等描述信息。
行内数据的数据行
对于行内数据,单个数据行最大可为8060字节。记录还可以在独立的页面上存储行溢出数据和LOB数据。一个给定页面上存在的行数根据表的结构及存储数据的不同而变化。一个所有列都是固定长度的表,在每个页面上存储的行数总是相同的,变长记录的存储情况根据真正输入的数据长度而定。保持短的记录长度可以使一个页面容纳更多的记录,从而较少I/O并提升缓存命中率。
行偏移矩阵
行偏移矩阵是2字节项组成的块,每个2字节项表示相应的数据行开始的偏移。每条记录在这个矩阵中对应一个2字节项。虽然这些字节不是与记录中的数据存储在一起,但他们确实影响到一个页面上容纳的记录数。这个偏移矩阵表示了记录在页面上的逻辑顺序。比如,如果一张表上有聚集索引,SQL Server就按照聚集索引键值的顺序来存储记录。这并不意味着记录在页面上的物理存储是按照聚集索引键值的顺序来的。实际上,偏移矩阵中的slot 0指向的是按照聚集索引键值的顺序的第一条记录,slot 2指向第二条,以此类推。
对于表中的每一条记录并没有一个内部的全局行编号。SQL Server使用(文件号、页号、页面上的slot号)三元组来唯一标识表中的每条记录。
数据行的结构
列偏移矩阵
一个所有列都是固定长度的数据行,既没有变长列数量也没有列偏移矩阵。一个有变长列的数据行中有一个列偏移矩阵,对于每个变长列有2字节的项用于表示其在行中结束的位置。
定长记录的存储
表包含四个定长列:Col 1 char(5),Col 2 int,Col 3 char(3) ,Col 4 char(6)
变长记录的存储
表含两个定长列和三个变长列:Col 1 char(3),Col 2 varchar(255),Col 3 varchar(5) ,Col 4 varchar(20),Col 5 int
行溢出数据
SQL Server 2005中,数据页面上单条记录的最大长度是8060字节,而变长列所能定义的最大长度为8000字节。
创建表(Col 1 char(3000),Col 2 char(3000),Col 3 char(3000))时,数据行最大长度超过允许范围,系统会报错。
为了突破这个8060字节限制,我们可以使用变长列,SQL Server可以将变长列存储在特定的行溢出页面。
创建表(Col 1 varchar(3000),Col 2 varchar(3000),Col 3 varchar(3000) ,Col 4 varchar(3000) ),然后插入数据(每个变长列的数据长度都为3000字节)。
系统将会创建一个常规数据页面和一个行溢出数据页面,常规数据页面的数据行保存前两个字段及指向行溢出列的指针,溢出数据页面保存后两个字段。
大数据对象(LOB)
如果一张表包含LOB数据(text/ntext/image),默认真实的数据不是存储在常规数据页面上。与行溢出数据一样,LOB数据被放在其自己的一组页面上。对于LOB列,SQL Server在数据行中只存储一个16字节的指针来表明在何处可以找到真正的数据。
思考:将LOB数据单独存储的好处?