sqlSERVER 数据库中数据如何存储是sqlSERVER 数 据库核心的知识, 同时网络上相关的参考资料也比较少! 近 段时间通过学习相关知识,将自己对sqlSERVER 数据库在数据存储方面的理解整理下来,一方面 希望能加深自己的印象,另一方面也希望能给其他的朋友提供相关的参考!
一:存储文 件类型
sqlSERVER 有 两种数据存储文件,分别是数据文件和日志文件。
其中:数据文件是以8K( =8192Byte) 的页面(Page) 作为存储单元的。
而日志文件是 以日志记录作为存储单元。
数据文件以页面做为存储单元存储数据,要理解数据文件的存储方式, 必须了解sqlSERVER 中定义的页面类型种类。
二: 页面类型
sqlSERVER 中页面类型有8 种, 具体每种类型的详细说明,见下图:
二: 页面类型
sqlSERVER 中页面类型有8 种, 具体每种类型的详细说明,见下图:
用户的数据一般存放在数据页面中, 由上图可以看出, 数据页包含数据行中除 text 、ntext 和 image 数据外的所有数据,text 、ntext 和 image 数据存储在单独的页中。 那么在一个数据页面中, 数据是如何存放,sqlSERVER 又 是根据什么来定位页面与页面上的数据呢。要回答这个问题, 有必要先了解数据页面的具体结构。
三:数据页面结构
在数据页上,数据行紧接着页首按顺序放置。在页尾有一个 行偏移表。在行偏移表中,页上的每一行都有一个条目,每个条目记录那一行的第一个字节与页首的距离。行偏移表中的条目序列与页中行的序列相反。
数据页面结构如下图所示,下面将详细解释
其中:数据页面页首:96 个字节,保存着页面的
系统信息,如页的类型、页的可用空间量、拥有页的对象的对象 ID 以 及
该页面 所属于哪个物理文件。
数据区:对应于上图中所有数据行的总 区域,存放真正的数据,是以 Slot 为单位。一个 Slot 就是对应于一条数据记录行,从 0 开始编号 , 以 16 进制反序保存 ,Slot0, Slot1.... 。
行偏移数组:用于记录该数据页面中每个 Slot 在数据页面所处的相对位置,便于定位和检索每个 Slot 在数据页面中的位置,数组中每个记 录占两个字节。
数据区:对应于上图中所有数据行的总 区域,存放真正的数据,是以 Slot 为单位。一个 Slot 就是对应于一条数据记录行,从 0 开始编号 , 以 16 进制反序保存 ,Slot0, Slot1.... 。
行偏移数组:用于记录该数据页面中每个 Slot 在数据页面所处的相对位置,便于定位和检索每个 Slot 在数据页面中的位置,数组中每个记 录占两个字节。
四:存储分配单位:盘区
(
扩展
Extend)
虽然 sqlSERVER 中数据文件存储单位是页面 (Page), 但实际 sqlSERVE 并不是为页面为单位给数据分配空 间, sqlSERVER 默认的存储分配单位是盘区。这样做的主要原因是为了提高性能。为了避免频繁的读写 IO ,在表或其它对象分配存储空间,不 是直接分配一个 8K 的页面,而是以一个盘区 (Extend) 为存储分配单位,一个盘区为 8 个页面 (=8 * 8K = 64K) 。
虽然 sqlSERVER 中数据文件存储单位是页面 (Page), 但实际 sqlSERVE 并不是为页面为单位给数据分配空 间, sqlSERVER 默认的存储分配单位是盘区。这样做的主要原因是为了提高性能。为了避免频繁的读写 IO ,在表或其它对象分配存储空间,不 是直接分配一个 8K 的页面,而是以一个盘区 (Extend) 为存储分配单位,一个盘区为 8 个页面 (=8 * 8K = 64K) 。
但是这样做虽然
减少了频繁的
IO
读写,提高的数据库性能,但却导致 出一个新问题,那就是在存储那些只有少量数据,不足
8K
的对象,如果也是分配给一个盘区,就 会存在存储空间上的浪费,降低了空间分配效率。
为解决上述问题,
sqlSERVER
提供了一种解决方案,定义了两种盘 区类型
,
统一盘区和混合盘区。
其中 : 统一盘区只能存放同一个对象,该对 象拥有这个盘区的所有页面
混合盘区:由多个对象共同拥有该盘 区。
在实际为对象分配存储盘区时,为了提高空间利用率,默认的情况下,如果一个对象一开始 大小小于 8 个页面,就尽量放在混合盘区中,如果该对象大小增加到 8 个页面后, sqlSERVER 会为这个对象重新分配一个统一盘 区。
其中 : 统一盘区只能存放同一个对象,该对 象拥有这个盘区的所有页面
混合盘区:由多个对象共同拥有该盘 区。
在实际为对象分配存储盘区时,为了提高空间利用率,默认的情况下,如果一个对象一开始 大小小于 8 个页面,就尽量放在混合盘区中,如果该对象大小增加到 8 个页面后, sqlSERVER 会为这个对象重新分配一个统一盘 区。
其中:
- 全局分配映射表 (GAM)
GAM
页 记录已分配的盘区, 包括统一盘区和混合盘区。每个GAM 包 含 64,000 个盘区,将近 4 GB 的 数据。GAM 对所涵盖区间内的每个盘区都有一位。如果这个位是 1 ,则盘区未分配( 可用) ;如果这个位是 0 ,则盘区已分配。
- 共享全局分配映射表 (SGAM)
SGAM
页 只记录混合盘区,这些盘区当前用作混合盘区而且至少有一个未使用的页。每个 SGAM 包含 64,000 个扩展盘区,将近 4 GB 的数 据。SGAM 对所涵盖区间内的每个扩展盘区都有一位。如果这个位是 1 ,则该扩展盘区就用作混合扩展盘区且有可用的页;如果这个位是 0 , 则该扩展盘区不用作混合扩展盘区,或者虽然用作混合扩展盘区但其所有页都正在使用中。
根 据扩展盘区的当前使用情况,每个扩展盘区在
GAM
和
SGAM
中有以下位模式设置。
通过这样的策略简化 了盘区管理算法。若要分配统一盘区,
sql Server
在
GAM
中搜索是
1
的位,然后将它设成
0
。若要查找有可用页的混合盘区,
sql Server
在
SGAM
中搜索是
1
的位。若要分配混合盘区,
sql Server
在
GAM
中搜索是
1
的位,并将它设置为
0
,然后将
SGAM
中相应的位也设置为
1
。若要释放盘区,
sql Server
应确保
GAM
位设置为
1
而且
SGAM
位设置为
0
。
sql Server
内部实际使用的算法比这里叙述的算法要复杂(
sql Server
在数据库中均匀分布数据),
,
但道理大致如此。
五:查看实际的数据页面信息
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。