SQLSERVER2000功略(2)-数据库的逻辑存储及检索
数据的存储及查找是数据操作的重要内容。在工作之前,了解一下内部的存储机制吧。
SQLSERVER在存储控件的管理上利用page和Extent这两种单位分配控件给数据库的。也就是说,我们建立的数据文件内部是利用page和Extent为单位来存放表和索引等对象的。首先,了解一下这两个概念:
Page
Page(页)是最基本的单位,每个page的大小为8KB。即使你的记录很小,SQLSERVER也要分配一个page给他的,当然用不到的空间可以存放新加入的记录。我们在这提醒的是:存放在page里的记录都是“完整“的,也就是说,要么完全保存在这个页中,要么再分配一个页进行存放,不会出现一个记录一部分存放在这个页上,另外的存放在其他页上的情况。
好,了解了他的大小,你会不会有个想法――这个页中真的能保存8KB的内容么?是不是很奇怪的问题?!这个的回答也许你猜到了:NO。由于里面的pageheader用来记录此页的相关信息,这个占去了96B,而每存一笔数据,页尾还要用掉2B的空间存放代表记录位置的row offset,所以一个页最多有8060B的空间来真正存放记录。是不是很没劲的算法,来看看数据页的图就省劲了:
看了这张图是不是更清楚了!现在我们看下一个问题,那就是text,ntext和iamge等类型的数据的存储。(由于这些数据的存储比较复杂,所以在此不详细叙述,只简单介绍一下,如果感兴趣朋友可以查询相应资料或者到论坛进行交流)
如图所示:这些数据的存储有些特殊,他们的数据是另外存储在专门的page上的。
访问text,ntext和image之类的数据时由于采用的间接查询,所以执行效率上相对其他类型较差,但是为了改善这种情况,SQLSERVER通过调用系统存储过程sp_tableoption来让这些类型像一般的数据一样存储和读取。
Extent
了解了page,其实Extent的理解就容易了。Page是存储数据的基本单位,Extent则是存储表,索引的基本单位。也就是说,表和索引由一笔一笔的数据组成,这些数据由page存放,而这些表则是由相当于8个page的Extent来存放。那你会问,为什么为Extent分配8个page哪?这个不就是64KB的空间么,是不是太多了?其实这个呀,主要也是为了性能而做的考虑。
好了,这些基本的单位我们就说些这个,其实还有很多基本的数据结构,我们在以后的学习中慢慢介绍。
简单的看了看存储结构,相信对SQLSERVER数据库的访问效率有一点体会了吧!下面我们就讨论一下对访问效率有重大影响的结构――索引。
从存储方式上讲,索引与表是相同的,但在结构上由于采用了B-Tree平衡树结构,所以复杂了很多。B-Tree结构最重要的特征之一,就是从根节点到任一个末节点的距离是等长的。这也就保证了查询的速度均等。图示如下:
这个结构是索引的基本结构,下面我们具体谈谈这个结构下的聚簇索引和非聚簇索引(也有称作聚集索引和非聚集索引的)。
聚簇索引:数据会因为有了索引而重新排列。因此,存取聚簇索引的数据比存取非聚簇索引的数据快速,因为他不需要额外的查询参考页与指针的过程。(注意:一个表只能建一个聚簇索引)。使用聚簇索引必须的考虑磁盘空间的问题,至少需要原数据量的120%,而这个空间必须在同一个数据库内。例如:一个数据库中表的数据量是10M,而这个数据库必须还有12M的空间,也就是说整个数据库的空间大小至少是22M。
聚簇索引从新排序后则替换掉原来的表。
非聚簇索引:非聚簇索引对原数据不重新排列。创建非聚簇索引与创建B+索引树一样。由于需要保存索引树,所以所需存储空间比聚簇索引多,但是创建过程中所需空间比聚簇索引小的多。
这两种索引是不是也很容易理解哪?在这里我们的强调:因为聚簇索引影响真个表的排列顺序,索引导致非聚簇索引的失效,因此,创建索引之前,规划好,先创建聚簇索引而后创建非聚簇索引。这也是一个好的习惯。由于非聚簇索引可以在不唯一的列上创建,但是我们不提倡这么做。
SQLSERVER查找数据有两种方式,一种使用索引找,另一种一行一行的扫描。这两种比较,不言而喻,当然是前者效率高,这也是为什么要创建索引的意义所在。
讲了上面这些,对存储和查询有没有点感觉哪,我们慢慢来,一起掌握吧!
SQLSERVER在存储控件的管理上利用page和Extent这两种单位分配控件给数据库的。也就是说,我们建立的数据文件内部是利用page和Extent为单位来存放表和索引等对象的。首先,了解一下这两个概念:
Page
Page(页)是最基本的单位,每个page的大小为8KB。即使你的记录很小,SQLSERVER也要分配一个page给他的,当然用不到的空间可以存放新加入的记录。我们在这提醒的是:存放在page里的记录都是“完整“的,也就是说,要么完全保存在这个页中,要么再分配一个页进行存放,不会出现一个记录一部分存放在这个页上,另外的存放在其他页上的情况。
好,了解了他的大小,你会不会有个想法――这个页中真的能保存8KB的内容么?是不是很奇怪的问题?!这个的回答也许你猜到了:NO。由于里面的pageheader用来记录此页的相关信息,这个占去了96B,而每存一笔数据,页尾还要用掉2B的空间存放代表记录位置的row offset,所以一个页最多有8060B的空间来真正存放记录。是不是很没劲的算法,来看看数据页的图就省劲了:
看了这张图是不是更清楚了!现在我们看下一个问题,那就是text,ntext和iamge等类型的数据的存储。(由于这些数据的存储比较复杂,所以在此不详细叙述,只简单介绍一下,如果感兴趣朋友可以查询相应资料或者到论坛进行交流)
如图所示:这些数据的存储有些特殊,他们的数据是另外存储在专门的page上的。
访问text,ntext和image之类的数据时由于采用的间接查询,所以执行效率上相对其他类型较差,但是为了改善这种情况,SQLSERVER通过调用系统存储过程sp_tableoption来让这些类型像一般的数据一样存储和读取。
Extent
了解了page,其实Extent的理解就容易了。Page是存储数据的基本单位,Extent则是存储表,索引的基本单位。也就是说,表和索引由一笔一笔的数据组成,这些数据由page存放,而这些表则是由相当于8个page的Extent来存放。那你会问,为什么为Extent分配8个page哪?这个不就是64KB的空间么,是不是太多了?其实这个呀,主要也是为了性能而做的考虑。
好了,这些基本的单位我们就说些这个,其实还有很多基本的数据结构,我们在以后的学习中慢慢介绍。
简单的看了看存储结构,相信对SQLSERVER数据库的访问效率有一点体会了吧!下面我们就讨论一下对访问效率有重大影响的结构――索引。
从存储方式上讲,索引与表是相同的,但在结构上由于采用了B-Tree平衡树结构,所以复杂了很多。B-Tree结构最重要的特征之一,就是从根节点到任一个末节点的距离是等长的。这也就保证了查询的速度均等。图示如下:
这个结构是索引的基本结构,下面我们具体谈谈这个结构下的聚簇索引和非聚簇索引(也有称作聚集索引和非聚集索引的)。
聚簇索引:数据会因为有了索引而重新排列。因此,存取聚簇索引的数据比存取非聚簇索引的数据快速,因为他不需要额外的查询参考页与指针的过程。(注意:一个表只能建一个聚簇索引)。使用聚簇索引必须的考虑磁盘空间的问题,至少需要原数据量的120%,而这个空间必须在同一个数据库内。例如:一个数据库中表的数据量是10M,而这个数据库必须还有12M的空间,也就是说整个数据库的空间大小至少是22M。
聚簇索引从新排序后则替换掉原来的表。
非聚簇索引:非聚簇索引对原数据不重新排列。创建非聚簇索引与创建B+索引树一样。由于需要保存索引树,所以所需存储空间比聚簇索引多,但是创建过程中所需空间比聚簇索引小的多。
这两种索引是不是也很容易理解哪?在这里我们的强调:因为聚簇索引影响真个表的排列顺序,索引导致非聚簇索引的失效,因此,创建索引之前,规划好,先创建聚簇索引而后创建非聚簇索引。这也是一个好的习惯。由于非聚簇索引可以在不唯一的列上创建,但是我们不提倡这么做。
SQLSERVER查找数据有两种方式,一种使用索引找,另一种一行一行的扫描。这两种比较,不言而喻,当然是前者效率高,这也是为什么要创建索引的意义所在。
讲了上面这些,对存储和查询有没有点感觉哪,我们慢慢来,一起掌握吧!