技术开发 频道

数据库索引一次性搞定

    【IT168 评论】1. 数据库的数据存储

  1.1文件:

  我们一旦创建一个数据库,都会生成两个文件:

  DataBaseName.mdf: 主文件,这是数据库中的数据最终存放的地方。

  DataBaseName.ldf:日志文件,由数据操作产生的一系列日志记录。

  1.2分区:

  在一个给定的文件中,为表和索引分配空间的基本存储单位。 1个区占64KB,由8个连续的页组成。 如果一个分区已满,但需存一条新的记录,那么该记录将占用整个新分区的空间。

  1.3 页:

  分区中的一个分配单位。这是实际数据行最终存放的地方。 页用于存储数据行。

  Sql Server有多种类型的页:

  Data, Index,BLOB,GAM(Global Allocation Map),SGAM,PFS(Page Free Space),IAM(Index Allocation Map),BCM(Bulk Changed Map)等。

  2. 索引

  2.1.1索引

  索引是与表或视图关联的磁盘上结构,可以加快从表或视图中检索行的速度。索引包含由表或视图中的一列或多列生成的键。这些键存储在一个结构(B 树)中,使 SQL Server 可以快速有效地查找与键值关联的行。

  通俗点说,索引与表或视图相关,旨在加快检索速度。索引本身占据存储空间,通过索引,数据便会以B树形式存储。因此也加快了查询速度。

  2.1.2聚集索引

  聚集索引根据数据行的键值在表或视图中排序和存储这些数据行。索引定义中包含聚集索引列。每个表只能有一个聚集索引,因为数据行本身只能按一个顺序排序。只有当表包含聚集索引时,表中的数据行才按排序顺序存储。如果表具有聚集索引,则该表称为聚集表。如果表没有聚集索引,则其数据行存储在一个称为堆的无序结构中。

  通俗点说,聚集索引的页存储的是实际数据。每个表只能建立唯一的聚集索引,但也可以没有。

  如果建立聚集索引,那么表中数据以B树形式存储数据。

  对于聚集索引的理解,打个比方,即英文字典的单词编排。 英文字典单词以A,B,C,D….X,Y,Z的形式顺序编排,如果我们查找 Good 单词,我们首先定位到G,然后定位o – o-d. 最终查找到Good,便是good实际存在的地方。

  建聚集索引需要至少相当该表120%的附加空间,以存放该表的副本和索引中间页。

  2.1.3非聚集索引

  非聚集索引具有独立于数据行的结构。非聚集索引包含非聚集索引键值,并且每个键值项都有指向包含该键值的数据行的指针。

  从非聚集索引中的索引行指向数据行的指针称为行定位器。行定位器的结构取决于数据页是存储在堆中还是聚集表中。对于堆,行定位器是指向行的指针。对于聚集表,行定位器是聚集索引键。

  通俗点说,非聚集索引的页存储的是不是实际数据,而是实际数据的地址。一个表可以存在多个非聚集索引。在Sql Server2005中,每个表最多可以建立249个,而在Sql server2008中,则最多可以建立999个非聚集索引。

  对于非聚集索引的理解,即新华字典的“偏旁部首”查字法。遇到您不认识的字,不知道它的发音,这时候,您就不能按照刚才的方法找到您要查的字,而需要去根据“偏旁部首”查到您要找的字,然后根据这个字后的页码直接翻到某页来找到您要找的字。但您结合“部首目录”和“检字表”而查到的字的排序并不是真正的正文的排序方法,比如您查“张”字,我们可以看到在查部首之后的检字表中“张”的页码是672页,检字表中“张”的上面是“驰”字,但页码却是63页,“张”的下面是“弩”字,页面是390页。很显然,这些字并不是真正的分别位于“张”字的上下方,现在您看到的连续的“驰、张、弩”三字实际上就是他们在非聚集索引中的排序,是字典正文中的字在非聚集索引中的映射。我们可以通过这种方式来找到您所需要的字,但它需要两个过程,先找到目录中的结果,然后再翻到您所需要的页码。我们把这种目录纯粹是目录,正文纯粹是正文的排序方式称为“非聚集索引”。

  2.1.4 覆盖索引:

  覆盖索引是指那些索引项中包含查寻所需要的全部信息的非聚集索引,这种索引之所以比较快也正是因为索引页中包含了查寻所必须的数据,不需去访问数据页。 如果非聚簇索引中包含结果数据,那么它的查询速度将快于聚集索引。

  但是由于覆盖索引的索引项比较多,要占用比较大的空间。而且update 操作会引起索引值改变。所以如果潜在的覆盖查询并不常用或不太关键,则覆盖索引的增加反而会降低性能。

  2.1.5 主键和索引

  主键:表通常具有包含唯一标识表中每一行的值的一列或一组列。这样的一列或多列称为表的主键 (PK),用于强制表的实体完整性。在创建或修改表时,您可以通过定义 PRIMARY KEY 约束来创建主键。 它是一种唯一索引。

  下面是一个简单的比较表

 主键
 
聚集索引
 
用途强制表的实体完整性对数据行的排序,方便查询用
一个表多少个
 
一个表最多一个主键
 
一个表最多一个聚集索引
 
是否允许多个字段来定义
 
一个主键可以多个字段来定义
 
一个索引可以多个字段来定义
 
是否允许 null 数据行出现
 
如果要创建的数据列中数据存在null,无法建立主键。
创建表时指定的 PRIMARY KEY 约束列隐式转换为 NOT NULL。
 
没有限制建立聚集索引的列一定必须 not null .
也就是可以列的数据是 null
参看最后一项比较
 
是否要求数据必须唯一
 
要求数据必须唯一
 
数据即可以唯一,也可以不唯一。看你定义这个索引的 UNIQUE 设置。
(这一点需要看后面的一个比较,虽然你的数据列可能不唯一,但是系统会替你产生一个你看不到的唯一列)
 
创建的逻辑
 
数据库在创建主键同时,会自动建立一个唯一索引。
如果这个表之前没有聚集索引,同时建立主键时候没有强制指定使用非聚集索引,则建立主键时候,同时建立一个唯一的聚集索引
 
如果未使用 UNIQUE 属性创建聚集索引,数据库引擎 将向表自动添加一个四字节 uniqueifier 列。
必要时,数据库引擎 将向行自动添加一个 uniqueifier 值,使每个键唯一。此列和列值供内部使用,用户不能查看或访问。
 

 

0
相关文章