四,表的存储原理

1. 内部存储概述

  创建一个表,就会有一行或多行插入到用来管理这个表的多个系统表里。至少要写信息到sysobjects、sysindexes和syscolumns这三个系统表里,当新建的表有外码约束时,相关的信息还会插入到sysrefrences系统表里。

  • Sysobjects(sys.tables)主要记录新表的基本信息,如表名、对象ID以及表的所有者等等。
  • Syscolumns主要记录新表列的信息,如列名、类型和长度等。
  • Sysindexes系统表记录包含指向新表所使用的存储空间的指针和有关新表大小的信息。
  • sysrefrences系统表里记录参照表的外键信息。

  

   注意:

  • 当一个新表刚创建时,在插入第一行数据之前系统不会立即为其分配存储空间,因此Sysindexes表中指示页地址和预留存储空间的列将都是0值。
  • 如果在该表上定义了PRIMARY KEY或UNIQUE约束,而PRIMARY KEY或UNIQUE约束的背后是由簇集索引支持的,则该表在Sysindexes中对应行的indid值为1。
  • 任何有非簇集索引支持的其他约束在Sysindexes表中都有一行,而且该行的indid值在2到250之间。

2. 数据行(记录)结构

  1、定长记录
  在定长记录里,每个字段都有固定的长度,而且字段数也是固定的。这种记录的字段能够连续存储,因此在给定记录地址的情况下,借助系统目录里有关字段的长度信息就能计算出某个特殊字段的地址。

  2、变长记录
  对于变长记录来说,一种可能的记录组织方式就是像定长记录一样连续地存放字段,字段之间通过分割符隔开。这种组织方式需要扫描记录才能定位需要访问的字段。

  另一种方法是在变长记录开始处预留一些空间作为存放一个整数偏移量数组的空间,数组中的第1个整数表示记录的第1个字段的起始地址,当然这个地址是相对于记录的起始地址的。另外在数组中也存储记录尾部的偏移量,这个偏移量用来识别最后一个字段的结束位置。

SQL Server定长记录的存储

  

  •  第1字节是状态位A,0x10表示只有第四位是1(从右向左以第0位开始),其他位都是0,因此该记录没有变长字段(如果位5为1,则存在变长字段);
  • 第2字节未使用;
  • 第3,4字节用于找到“字段数”的位置,其值1800,交换字节是0x0018,十进制是24;
  • col1字段数据从偏移量4开始,col2字段数据从偏移量8开始,col3字段数据从偏移量13开始,col4字段数据从偏移量16开始,col3字段的3字节全是0,说明该字段是NULL;
  • 偏移量24为起始的两字节是列数(字段数),保存着该条记录的总字段数,0400交换字节后是0x0004,表示该记录有4个字段;
  • 最后1字节是NULL位图,其值0x04意味着只有第三位是1,表示第三个字段是NULL。

  定长记录总是用满在表中定义的字节数,即使某个字段的值是NULL。

SQL Server变长字段记录的存储

   

  •  状态位A的值为0x30第5位为1,表示存在变长字段;
  • 通过第3,4字节找到,总字段数的位置;
  • 总字段数的两字节和NULL位图的1字节之后,就是变长字段数的两字节0300,交换字节后是0x0003,十进制是3,说明该记录有3个变长字段存在;
  • 变长字段数后就是变长字段偏移数组,每个变长字段使用两字节记录该字段在记录中的结束位置,图中第2个变长字段与第1个变长字段结束位置相同,说明第二个变长字段实际长度为0,所以具有NULL值的变长字段,在记录中是不占用空间的;
  • SQL Server根据NULL位图来区分一个变长字段的值是NULL还是空串;
  • 变长字段在记录中的长度与表明定义的长度并不一样,变长字段的长度是根据当前存入的数据的具体长度确定存储长度。

  注意:在页中整个记录的开销还包括页的底部用于记录每行的行偏移数组的两个字节。

原文地址:https://www.cnblogs.com/a-qi/p/13052470.html