1、写在前面

微软专门给出SQL Server设计思路及实现路线,从7大体系结构阐述是如何实现,通过了解这些,我们就可以总结出数据库设计原则编程中sql写法及注意事项,从而优化我们的系统性能,本系列着重讨论SQL Server索引体系。

以下为主要内容:

  • 页和区体系结构
  • 表和索引数据结构体系结构
  • 查询处理体系结构
 
2、数据存储结构

文件->系统页->区->页

2.1 区与页

页是SQL Server存储数据的最小单元,每个页文件大小8K,每个页会存放不同页类型的数据,页主要由以下部分组成。

  • 页头:标头
  • 数据区:数据行和可用空间
  • 行偏移数组:行偏移量数组指示页上行的逻辑顺序

另外,需要注意的是,磁盘I/O操作在页级执行。

区就是一个集合概念,它是由8个物理上连续的页构成的,区有助于有效管理页。

对SQL Server而言,其页类型有很多种

类型

英文

描述

作用

1

Data Page

数据页

存储行数据、聚集索引叶、位置随机

2

Index Page

索引页

非聚集索引、聚集索引非叶子、位置随机

3

Text Mixed Page

 

位置随机

4

Text Page

LOB的单列值

位置随机

7

Sort Page

临时表操作页

位置随机

8

GAM Global allocation Map

全局分配表

每个区都记录一个对象,每个文件第二页时GAMP,每位表示该区是否可用

9

SGAM Shared Global Allocation map

全局共享分配表

每个区都记录混合对象数据,每个文件的第三页

10

IAM Index Allocation Map

索引分配图

记录表对象数据存储在哪些区,将这些区连在一起就构成一个表数据存储。

11

Page Free Space

自由空间页

记录每页自由空间情况,每个字节代表一个页

13

Boot Page

启动页信息

 

14

Server Configuration Page

服务配置信息

 

15

File Header Page

文件头信息

总是在第0页

16

Differential Changed map

 

每个文件第6页,上次备份差异化

17

Bulk Change Map

 

每个文件第7页,上次备份批量差异化

问题

1. 头部为什么要96字节,它记录什么东西?

2. 数据行系统开销是什么,为什么是7字节,它怎么记录数据的?

3. 行偏移量数据干啥用的?

4. 数据是怎么通过数据页完成CURD的?

5. 怎么观测到页内容?

2.1.1 页头
 
  • 存储页的系统信息,固定长度96字节。
  • 记录页所在存储位置,页间双链表关系,页存储空间信息,页数据事务数据情况。
  • 根据这些情况,可判定是否要插入新数据、插入什么位置、涉及事务如何回滚、还原

2.1.2 数据行

行头系统信息存储:

Bit 0 位,版本信息

Bits 1-3 位,行记录类型

0,primary record,主记录

1:forwarded record

2:forwarding stub

3:index record,索引记录

4:blob或者行溢出数据

5:ghost索引记录

6:ghost数据记录

Bit 4 位,NULL位图

Bit 5 位,表示行中有变长列

Bit 6 位,保留

Bit 7 位,ghost record(幽灵记录)

数据行大小计算公式:定长位数据大小+变长数据大小+空行数+4

最小系统开销:行头(2)+定长列数(2)+空(1)+变长列数(2)

注意:定长和变长是针对字符型数据而言的

  • 注意:表格中关于Char不定长字符数据的描述是错误,所以配了第二张图

1. 转发存根和转发记录的产生

数据更新时,产生转发存根、转发记录。

如果一个数据页已经填满了,但对它某行的某一变长列更新时,此列的更新长度大于当前长度导致该数据页的字节数大于8192字节时,系统会拿出最长的列,存到Row overflow Data数据页中。当前页的某行某列存放转发存根24字节,另外一个数据页存放列数据。转发行指针24字节。

由此产生几个问题

  • 对查询危害是,查询该行时的数据至少要查询2个数据页。
  • 对更新时,数据是否满,是否要新增或删除转发存根记录。

2. 鬼影索引、鬼影数据、鬼影版本?的产生

当做delete操作时,系统不是立马删除数据,而是在数据行里标记鬼影记录,为了防止与查询互斥,标记一个鬼影版本。如果该表有索引,那么相应的索引页里索引行也标记鬼影数据记录。方便事务回滚操作。如果事务都结束了,由鬼影服务程序每过默认5秒会删除鬼影数据。数据页的页头也会标记有鬼影记录。

2.1.3 行偏移量数据 
 
  • 行偏移是一个个小块组成的,每个小块2个字节,表示数据行从第几个字节后开始记录,也就是距离页头多少偏移量开始记录
  • 存储方式是从游往左存储,用槽位来描述,slot 0 ,slot 1 ....
  • 行偏移量记录的内容是什么呢?该行记录从哪个字节开始,一般情况下,slot 1 从第96个字节后开始
  • 常说的聚集索引存储顺序是物理排序,指的不是行记录物理排序,而是行偏移量物理排序,数据页中,行记录都是顺序往后添加的,通过修改行偏移量来达到聚集索引的顺序查找

Slot array,行偏移量数组系统至少会保留36字节,每2字节表示1列。

每一行的数据内容最多不能超过8053,因为SQL Server还需要对每一行的数据最少附加7字节的系统数据。

2.1.4 数据库表设计与操作注意事项

表设计注意事项

1. 保持表中列的总长度不超过以公式为准(防止 row overflow data、blob data)

8192-96-(2+定长列总长度+2+空值列个数/8+变长列数2+(变成长列长度+2列偏移量))

  • 只有定长位:固定长列总长度<8192-96-2-2-2-列数/8
  • 只有变长列:变长列总长度<8192-96-2-2-2-列数/8-2*变长列数偏移量
  • 有变长和定长:固定长列总长度+变长列总长度<8192-96-2-2-列数/8-2*变长列数-变长列数*2
  • 完美表设计:(固定长列总长度+变长列总长度)N倍=8192-96-2-2-2-列数/8-2*变长列数偏移量-2N

2. 每个变长列最好是填充满,更新时页更新满。

如果有变长列,在做更新时列长度不一致。当一个数据页满时,如果更新的列数据长度大于现有数据,则会出现行溢出(row overflow data)。造成查询时多查找一次。

3. 最好不要出现null列,null列也会造成 row overflow data。当数据页满时,更新数据时也会产生。

操作注意事项

1. 更新操作变长列时,最好保持长度一致。避免row overflow data。

2. 查询时尽量指定列,如果查询所有列时会发生查找到的行的某一变长列,有可能另外row overflow data 页查找。多查询一次。

  • 为什么不建议使用Select *????
 
2.1.5 相关类型页结构
索引页和索引叶子页结构
  • 非聚集索引存储结构:
    • 索引值+Page页码 Btree中间位
    • 索引值+Page页码+主键值 Btree叶子节点
  • 聚集索引存储结构
    • 索引值+Page页码 Btree中间位
    • 数据行 Btree叶子节点
1、系统空间分配情况
区分配情况GAM和SGAM

GAMP:Global Allocation Map Pages 全局映射分配表,区属于一个对象.

SGAMP:Shared Global Allocation Map Pages 全局共享映射分配表,区属于不同对象.

页空间分配情况PFS (Page free space)

用于跟踪页可用空间情况,每个字节代表一个页信息,总共可以记录8088页情况,

还有8个字节哪里去?

系统通过GAM和SGAM管理区空间分配情况,通过PFS管理页空间使用情况


2、IAM 索引分配页

将表或视图对象通过IAM将(Data page、Index page、row overflow page、blob page)对于同一对象,每种数据类型都会产生IAM页,IAM用于管控对象包含哪些页文件,每8个页为一个独立区。

GAM-SGAM-IAM状态位表示


3、备份与还原 DCM和BCM

DCM:differential change map 差异变更映射图。

差异化备份时,DCM有效。

用于记录每个区自上次完全备份后是否发生变更,每个位表示1个区,1表示修改过,0表示未变更。记录8096*8个字节。

如果一个区内某个页发生变更该区会被记录变更过,但进行差异化备份时,会对发生变更的区进行备份,差异化备份减少备份量。

BCM:Bulk Change Map:批量表更映射图。

在做简单备份和完全备份两个模式中,BCM无效。

当sqlserver发生批量操作时,日志并不是完全记录而是最小化记录,如果备份采用日志备份,并不能完全回滚数据。那么BCM就为这样的批量操作做了记录。BCM责任记录每个区自上次完全日志备份后是否发生批量操作。每位记录一个区是否有批量操作,每个页记录当前页是否有批量操作记录。记录8096*8字节。

【野草】SQL Server之索引解析(一)的更多相关文章

  1. SQL Server之索引解析(一)

    SQL Server之索引解析(一)   1.写在前面 微软专门给出SQL Server设计思路及实现路线,从7大体系结构阐述是如何实现,通过了解这些,我们就可以总结出数据库设计原则.编程中sql写法 ...

  2. 【野草】SQL Server之索引解析(二)

    1.堆表 堆表通过IAM连接一起,查询时全表扫描. 1.1 非聚集索引 结构 叶子节点数据结构:行数据结构+Rid(8字节) 中间节点数据结构: (非聚集非唯一索引)行数据结构+Page(4)+2+ ...

  3. SQL Server之索引解析(二)

    1.堆表 堆表通过IAM连接一起,查询时全表扫描. 1.1 非聚集索引 结构 叶子节点数据结构:行数据结构+Rid(8字节) 中间节点数据结构: (非聚集非唯一索引)行数据结构+Page(4)+2+ ...

  4. SQL Server 数据加密功能解析

    SQL Server 数据加密功能解析 转载自: 腾云阁 https://www.qcloud.com/community/article/194 数据加密是数据库被破解.物理介质被盗.备份被窃取的最 ...

  5. 公司内部培训SQL Server传统索引结构PPT分享

    公司内部培训SQL Server传统索引结构PPT分享 下载地址 http://files.cnblogs.com/files/lyhabc/SQLServer%E4%BC%A0%E7%BB%9F%E ...

  6. SQL Server创建索引(转)

    什么是索引 拿汉语字典的目录页(索引)打比方:正如汉语字典中的汉字按页存放一样,SQL Server中的数据记录也是按页存放的,每页容量一般为4K .为了加快查找的速度,汉语字(词)典一般都有按拼音. ...

  7. 理解SQL Server中索引的概念

    T-SQL查询进阶--理解SQL Server中索引的概念,原理以及其他   简介 在SQL Server中,索引是一种增强式的存在,这意味着,即使没有索引,SQL Server仍然可以实现应有的功能 ...

  8. SQL Server 数据库索引

    原文:SQL Server 数据库索引 一.什么是索引 减少磁盘I/O和逻辑读次数的最佳方法之一就是使用[索引] 索引允许SQL Server在表中查找数据而不需要扫描整个表. 1.1.索引的好处: ...

  9. SQL Server创建索引

    原文:SQL Server创建索引 什么是索引 拿汉语字典的目录页(索引)打比方:正如汉语字典中的汉字按页存放一样,SQL Server中的数据记录也是按页存放的,每页容量一般为4K .为了加快查找的 ...

随机推荐

  1. (汇总)os模块以及shutil模块对文件的操作

    ''' # os 模块 os.sep 可以取代操作系统特定的路径分隔符.windows下为 '\\' os.name 字符串指示你正在使用的平台.比如对于Windows,它是'nt',而对于Linux ...

  2. 如何在ES5与ES6环境下处理函数默认参数

    函数默认值是一个很提高鲁棒性的东西(就是让程序更健壮)MDN关于函数默认参数的描述:函数默认参数允许在没有值或undefined被传入时使用默认形参. ES5 使用逻辑或||来实现 众所周知,在ES5 ...

  3. 判断NaN in JavaScript

    [NaN 作用是用来表示一个值不是数字] NaN在JavaScript中行为很怪异,是因为那NaN和任何值都不相等(包括它自己).            NaN === NaN; // false因为 ...

  4. compose合并函数依次执行 - 来源redux

    function compose(...funcs) { if (funcs.length === 0) { return arg => arg } if (funcs.length === 1 ...

  5. 计算机网络相关:应用层协议(一):DNS

    DNS 1.概念  DNS是:  1)  一个有分层的DNS服务器实现的分布式数据库  2)一个使得主机能够查询分布式数据库的应用协议.  它运行在UDP之上,默认使用53号端口.  主要功能 是将主 ...

  6. j2ee中spring的分布式事务实现及解决方案

    1 java事务类型 Java事务的类型有三种:JDBC事务.JTA(Java Transaction API)事务.容器事务. 常见的容器事务如Spring事务,容器事务主要是J2EE应用服务器提供 ...

  7. Spring加载xml配置文件的方式 ApplicationContext

    大家都知道Java读普通文件是通过Basic I/O 中的InputStream.OutStream.Reader.Writer 等实现的.在spring 框架中,它是怎样识别xml这个配置文件的呢? ...

  8. JQ无缝轮播图-插件封装

    类似京东的这种无缝轮播效果: 实例代码下载 HTML代码: <body> <!-- /*觅me 探索生活*/ --> <div class="test" ...

  9. Windows下安装配置go

    基于 go 1.9.2 + liteIDE + windows10 先安装 go 安装包,作用如同安装框架. 默认安装路径是 C:\Go,通常都会更改,但这会影响到后面设置环境变量,因此更改到哪里请记 ...

  10. python函数调用的四种方式 --基础重点

    第一种:参数按顺序从第一个参数往后排#标准调用 # -*- coding: UTF-8 -*- def normal_invoke(x, y): print "--normal_invoke ...