存储结构与索引

一、SQL数据存储的基本介绍

       数据库中的数据存储涉及页(Page)和区(Extent)这两个概念了。SQL server中数据存储的基本单位是页。为数据库中的数据文件(.mdf或.ndf)分配的磁盘空间可以从逻辑上划分成页(从0到n连续编号),磁盘I/O操作在页级执行。也就是说,SQL Server读取或写入数据的最小单位是以8KB为单位的页。区是8个物理上连续的页的集合,用来有效地管理页。如果区内的8个页属于同一个表,则这种区称为统一区;如果区内的8个页分别属于至少两个不同的表,则这种区称为混合区。页在SQLScrver中,大小为8KB。这意味着SQL Server数据库中每MB有128页。每页开头是一个96字节的页头,用于存储有关页的系统信息。包括页码、页类型、页的可用空间,以及拥有该页的对象的分配单元ID。不同类型的数据,存储在不同类型的页面里。在数据页的存储结构里,每个页的前面96个字节是页头。SQL server通过这96个字节的页头和系统表,从逻辑层面上把表的存储结构管理起来。针对表的存储结构,SQLserver引入了一些概念:这些概念包括:object(对象)、partition(分区)、Hobt(堆或 B 树)、allocation_unit(分配单元)。

       表存储结构的关系如图所示、每张表会有一个对应的objectID,同时每张表拥有一个或者多个Partition(通常一个Partition对应一个索引)。每个Partition会有一个或者多个Heap or B一Tree(简称为Hobt)。Hobt的结构是预留的,通常可以认为,Partition与Hobt是一样的,PartitionID就是HobtID。每个Hobt会有至多三个分配单元用于存放数据,分别是data(数据)、LOB(大数据字段类型)、Row-Overflow(行溢出)。最频繁使用的分配单元是Data。如果有LOB数据或者长度超过8000字节的记录,则可能有另外的LOB分配单元和Row一Overflow分配单元:一个表可以有多个Partition,但是每个Partition以Hobt最多有三个分配单元,每个分配单元可以有许多页。

 

二、索引对数据存储的影响

对于每个分配单元内的数据页,根据表是否有索引,以及索引是聚焦索引或非聚焦索引,其组织方式常见有以下三种:

1、没有索引

在这种情况下,数据是按堆的结构存储,只有一个分区,在系统表里,对于这个分区下面的每个分配单元都有一个连接指向Index Allocation Map页(IAM,索引指引页),在IAM页里,描述了区的信息。数据页之间没有任何关系,完全依赖IAM页组织起来。对于这种表的查询,数据库会先查询IAM页,任何根据其提供的信息,遍历所有区,将符合条件的页返回。其结构入下图所示:

 

PS:表、分区信息等可通过以下系统表查询

 

1 --查询表的信息
2 select *from sys.objects where name='test3'
3 --查询分区信息
4 select *from sys.partitions where object_id='1909581841'
5 --查询分配单元信息
6 select *from sys.allocation_units where container_id='72057594041335808'
View Code

 

 

2.有非聚集索引但没聚集索引

 这种情况下,数据依然是以堆结构存储,不过针对每个非聚集索引,都会有一个对应的partition。对于这个partition下面的每个分配单元,都有一个连接指向根页。数据页之间通过前后指针互相关联,在其结构底层,会有一个连接(文件号、页号、行号)指向真正的数据。其结构如图所示:

 

 

3、表有聚集索引

当表有索引时,其索引号为1,它有一个对应的partition,同样这个partition下的分配单元都会连接到一个根页,不过对于聚集索引来说,它在叶子节点上直接存储真正的数据,其结构如下:

 

 三、样例分析

创建3个样例表并插入相同的数据,其中test1无索引,test2只有非聚集索引,test3有聚集索引:

 1 use TEST;
 2 
 3 create table test1
 4 (
 5      id int not null,
 6      name char(10) null,
 7      test varchar(max) null,
 8 )
 9 
10 
11 create table test2
12 (
13      id int not null,
14      name char(10) null,
15      test varchar(max) null,
16 )
17  CREATE NONCLUSTERED INDEX NCL_TEST_ID ON test2 (id)
18 
19 
20 create table test3
21 (
22      id int not null primary key,
23      name char(10) null,
24      test varchar(max) null,
25 )
View Code

然后执行以下语句,查询分配单元情况:

 1 select e.*from sys.objects as a
 2 inner join
 3 sys.partitions as b
 4 on a.object_id=b.object_id
 5 inner join
 6 sys.allocation_units as c
 7 on b.partition_id=c.container_id
 8 inner join
 9 sys.system_internals_allocation_units as e
10 on c.allocation_unit_id=e.allocation_unit_id
11 where a.name='test1'
12 
13 
14 select e.*from sys.objects as a
15 inner join
16 sys.partitions as b
17 on a.object_id=b.object_id
18 inner join
19 sys.allocation_units as c
20 on b.partition_id=c.container_id
21 inner join
22 sys.system_internals_allocation_units as e
23 on c.allocation_unit_id=e.allocation_unit_id
24 where a.name='test2'
25 
26 select e.*from sys.objects as a
27 inner join
28 sys.partitions as b
29 on a.object_id=b.object_id
30 inner join
31 sys.allocation_units as c
32 on b.partition_id=c.container_id
33 inner join
34 sys.system_internals_allocation_units as e
35 on c.allocation_unit_id=e.allocation_unit_id
36 where a.name='test3'
View Code

得到结果如下图所示:

 

 

 

 

 

 从图中可以看到,它们都有data、lob这两种分配单元,无索引的跟只有聚集索引的都是具有相同数量的partition以及页,有非聚集索引的多了一个partition以及2页数据来记录。

PS:可通过以下语句查询更详细的partition信息:

1 dbcc ind('test','test1',1)
2 dbcc ind('test','test2',1)
3 dbcc ind('test','test3',1)
4 
5 --dbcc page可查看详细页的信息
View Code

四、总结

1.无索引情况下数据以堆结构存储,开iam页来引导检索,对于大表来说,建议建立聚集索引使数据有序化,便于处理;

2.非聚集索引是使用额外的存储来增加检索效率,对最底层的数据结构没影响;

3.聚集索引不会增加额外的存储,但会使底层的数据有序化;

 

转载于:https://www.cnblogs.com/9284chc0r0ij/p/10679373.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/277982.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

面向全球用户的Teams app之时区篇

我在前两篇文章里分享了Global Ready的app时会遇到的不同文化的挑战。这篇我继续分享在时区方面的挑战。 时间是最复杂的,最容易出错的部分。时间复杂的最根本原因是时区问题。 首先,大家都知道,我们地球是圆的,这个意味着如果大…

Linux: Nginx proxy_pass域名解析引发的故障

背景 业务架构: 部署细节:  两容器均部署在同一机器上,通过 docker-compose 编排,并且通过link方式链接。 故障描述 在有次更新代码时,发现前端能够打开,但是所有接口请求全是502(Bad GateWay) 故障排查 …

Oracle建立全文索引详解

Oracle建立全文索引详解1.全文检索和普通检索的区别 不使用Oracle text功能,当然也有很多方法可以在Oracle数据库中搜索文本,比如INSTR函数和LIKE操作: SELECT *FROM mytext WHERE INSTR (thetext, Oracle) > 0; SELECT * FROM mytext WHE…

面向全球用户的Teams app之夏令时篇

我在前两篇文章里分享了Global Ready的teams app时会遇到的不同挑战。这篇我继续分享在夏令时方面的挑战。 夏令时,主要是为了节约能源,英文里通常缩写成DST(Daylight Saving Time)。一般在天亮早的夏季人为将时间调快一小时,可以使人早起早…

面向全球用户的Teams app之合规性篇

我在前两篇文章里分享了Global Ready的app时会遇到的不同挑战。这篇我继续分享在合规性方面的挑战。 说到合规性compliance,不得不说GDPR标准,当我们发布了一个teams app后,微软会要求开发人员做一个security self assessment,这…

行内元素中去掉文字的上下间距,使得文字所在元素的高度同字体高度一致的方法...

之前在p这类块元素中的文字,给line-hight1;就可以去掉文字自带的上下间距, 像这样: 最近突然发现这个方法在行内块和块元素上好使,可当用在span或者a这类内联元素上都不好使,除了转为块元素的方法来去掉上下间距&#…

VSCode的Teams插件

随着今年在线的Build大会的结束,又是一大波的 Teams 新功能,新工具,新SDK。我接下来几篇博客就会详细和大家一一介绍。我今天先从VSCode的插件开始。 打开VS Code,搜索Teams,就可以找到Microsoft Teams Toolkit插件&a…

使用Flow快速开发Teams小应用

继续我的上一篇博客,这篇继续介绍BUILD大会里的内容:Flow。 Flow是微软power平台的一个服务,通过简单的拖拽就可以完成一个业务逻辑的处理,现在Flow和Teams的结合十分紧密。我们来试一下。 先点击Teams左边的Flow菜单。 如果你的…

python正则中如何匹配汉字以及encode(‘utf-8’)和decode(‘utf-8’)的互转

正则表达式&#xff1a;  [\u2E80-\u9FFF]$ 匹配所有东亚区的语言   [\u4E00-\u9FFF]$ 匹配简体和繁体   [\u4E00-\u9FA5]$ 匹配简体   <input type"text" name"username" οnkeyup"valuevalue.replace([\u4E00-\u9FA5]$)"> 正则表…

【区块链】认识区块链的基本概念

2018年区块链技术风卷全球&#xff0c;似乎大家都在谈论区块链&#xff0c;那到底什么区块链&#xff0c;区块链到底能干什么&#xff0c;对普通人会有什么影响&#xff0c;很多人还是稀里糊涂&#xff0c;那么就谈谈我的一些理解吧&#xff0c;抛砖引玉欢迎探讨。 我是如何接触…

将Teams Template升级到dotnet core 3.1

为了方便开发者开发Teams应用&#xff0c;我在2018年做了dotnet c#的一套模板&#xff0c;这套模块一共有三种类型&#xff0c;一个是Teams OutgoingWebhook&#xff0c;一个是MessagingExtension&#xff0c;还有一个就是Tab。 今天特地去nuget上看了一下&#xff0c;下载量还…

【动态规划】cf1034C. Region Separation

质因数分解套路的复杂度分析的动态规划 题目大意 有一颗$n$个节点有点权的树&#xff0c;初始整棵树为$1$号区域&#xff0c;要求满足下列规则&#xff1a; 除非$i$是最后一个等级&#xff0c;否则每一个$i$级区域都要被分成至少两个$i1$级区域对于每种等级&#xff0c;每个点必…

【数据结构】线性表(一):顺序列表

线性表(linear_list)是最常用且最简单的一种数据结构&#xff0c;简言之&#xff0c;一个线性表是n个数据元素的有序序列。 例如&#xff1a;&#xff08;a1 , ... , ai-1 , ai , ai1 , ... , an)&#xff1a;ai-1 是 ai 的直接前驱&#xff0c;ai1 是 ai 的直接后驱。 并且&am…

校招需要看的书 巩固的知识

前言 感谢教练&#xff0c;学长们&#xff0c;队友&#xff0c;lollipop&#xff0c;猫哥&#xff0c;李哥&#xff0c;表哥&#xff0c;鸡哥&#xff0c;样样&#xff0c;咸糖&#xff0c;茗记&#xff0c;明沙&#xff0c;嘻&#xff0c;树佬(排名不分先后)等等太多太多的人的…

Teams Tab的Single Sign-On

在我写这篇文章的时候&#xff0c;这个SSO机制还是在 Developer Preview 阶段&#xff0c;可能在发布前还会有一些改进。不过我觉得这个功能很好&#xff0c;所以先和大家分享一下。 如果大家之前已经开发过Teams的tab应用&#xff0c;可能会发现如果你需要一个当前用户的toke…

算法引入

算法的概念&#xff1a; 解决问题的思路。 时间复杂度&#xff1a; 定义&#xff1a; 基本运算的执行数量。是算法效率的衡量的量。 计算准则&#xff1a; 基本操作&#xff1a;即只有常数项。复杂度认为1顺序&#xff0c;按照加法计算循环&#xff0c;按照乘法计算条件。按照最…

如何开发Teams Bot

很多朋友问我如何开发一个成功的Teams Bot&#xff0c;他们说Bot Framework SDK看起来简单&#xff0c;但是真要的去开发一款成熟的bot&#xff0c;很多地方还是不知道如何使用。我从最早的bot framework还在beta的时候开始用&#xff0c;后来framework经历了多次大的改动&…

P1579哥德巴赫猜想

写来自己学习用~ 题目内容&#xff1a; 1742年6月7日哥德巴赫写信给当时的大数学家欧拉&#xff0c;正式提出了以下的猜想&#xff1a;任何一个大于9的奇数都可以表示成3个质数之和。质数是指除了1和本身之外没有其他约数的数&#xff0c;如2和11都是质数&#xff0c;而6不是质…

在VSCode Remote环境下开发Teams Bot

我使用VS Code开发已经有蛮长一段时间了&#xff0c;时间长了&#xff0c;越来越喜欢VS Code&#xff0c;虽然有些时候会没有传统的VS方便&#xff0c;比如开发Azure Function时你需要编写一下launch.json&#xff0c;而且你需要手动启动StorageEmulator&#xff0c;但是也正是…

查看安卓APK源码破解

原文:查看安卓APK源码破解工具准备&#xff1a; <1>.android4me的AXMLPrinter2工具 <2>dex2jar <3>jd-gui 工具下载&#xff1a;http://download.csdn.net/detail/catshitone/8491347 开始&#xff1a; 第一步&#xff1a; 首先用解压软件&#xff08;如好…