一、索引的结构

关系型数据库中以二维表来表达关系模型,表中的数据以页的形式存储在磁盘上,在SQL SERVER中,数据页是磁盘上8k的连续空间,那么,一个表的所有数据页在磁盘上是如何组织的呢?分两种情况:

一是数据页间无序、随机地存储在磁盘上,这样的表叫做堆表(表上无聚集索引);

二是数据页间按某个表字段的值有序地存储在磁盘上,这样的表做索引组织表(表上有聚集索引)。

 

索引是什么?从物理结构上可分为两种:聚集索引和非聚集索引。将表中的数据有序地组织起来的索引称为聚集索引,一个表只有一个聚集索引,表上其他的B树索引都是非聚集索引。

1.1、聚集索引结构

(1)聚集索引将表内的数据进行有序的组织,并不是指磁盘上数据页内数据的物理顺序,也不是指数据页在磁盘上的物理顺序,而是数据页间逻辑上以树型结构链接起来,结构如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
create  table  t
(
ID        int ,
NAME      varchar (100)
AGE       int ,
)
GO
INSERT  INTO  VALUES (1, '张一' ,20)
INSERT  INTO  VALUES (2, '张二' ,25)
INSERT  INTO  VALUES (4, '张三' ,21)
INSERT  INTO  VALUES (5, '李二' ,23)
INSERT  INTO  VALUES (7, '李三' ,24)
INSERT  INTO  VALUES (8, '李四' ,22)
GO
create  CLUSTERED  index  IX_t_ID  on  t(ID)

索引组织表中的数据页,除了有IAM页进行管理,页之间还有单向或者双向链表连接。

 

(2)聚集索引的非叶子节点(即索引节点),只包含下一节点的第一个键值(入口键值)及指向下一节点页的指针,指针的格式为:文件编号+页编号,长度为2Byte+4Byte=6Byte;

 

(3)聚集索引的叶子节点行就是表中的数据行;

 

(4)没有聚集索引的表,结构如下:

堆表中的数据页之间没有链表连接,随机的存放在磁盘上,仅通过IAM页进行管理。

 

(5)数据库引擎根据系统表判断当前表为堆表/索引组织表,并查得堆表的first_IAM_page/索引组织表的first_page,即可对表展开扫描;

 

(6)堆表和索引组织表包含的数据行是一样的,只是组织形式不同而已;

 

1.2、非聚集索引结构

(1)非聚集索引是对聚集索引的索引,结构如下:

 

(2)非聚集索引的索引节点和聚集索引一样,只包含下一节点的第一个键值(入口键值)及指向下一节点页的指针,指针的格式为:文件编号+页编号,长度为2Byte+4Byte=6Byte;

 

(3)非聚集索引的叶子节点存储的是索引列和书签。

如果是堆表,书签为ROWID,长度为8Byte,即数据页号(4Byte)+文件号(2Byte)+槽号(2Byte)的行定位串;

如果是索引组织表,书签为聚集索引键;

1
2
3
create  NONCLUSTERED  index  IX_t_AGE  on  t(AGE)
GO
SELECT  FROM  WHERE  AGE=20

此时想要根据年龄20来查找数据。

如果是堆表,先根据AGE找的应该是ID=1这一行数据的8字节的ROWID,然后再根据这个ROWID去找到该行的所有数据,即(1,'张一',20);

如果是索引组织表,先根据AGE上的非聚集索引找到ID,此时ID值为1,然后再将ID=1带入聚集索引进行等值查找,最终在聚集索引的叶子节点得到该行的所有数据;

 

(4)无论是聚集索引还是非聚集索引的叶子节点上都有一个指向上下页的指针。

 

二、索引分类

1、SQL SERVER中索引分类

(1)B+树索引

目前关系型数据库中一种常见的索引组织结构。B+树,它是一多叉平衡排序树,直到叶子节点才会命中数据,以下简称B树,可参见相关《数据结构》的书籍;

 

(2)全文索引

目前关系型数据库一种基于标记的索引组织结构,它不是B树结构,而是基于要索引的文本中的各个标记来创建倒排、堆积且压缩的索引结构。

 

(3)XML索引

随着XML文本的应用,在各个关系型数据库中也相继提供了对这种数据结构的支持。XML 实例作为二进制大型对象 (BLOB) 存储在 xml 类型列中。对于列中的每个 XML对象,索引将创建几个数据行。该索引中的行数大约等于 XML对象中的节点数。

 

2、B树索引的分类

2.1、物理结构分类

(1)聚集索引

根据索引列值,按B树结构对表内数据进行组织;

 

(2)非聚集索引

对聚集索引的索引;

 

2.2、列值唯一性分类

(1)唯一索引

表中索引列的值唯一。

SQL SERVER在唯一性上认为NULL是相等的(ORACLE中唯一键是可以插入多个NULL值的),即唯一键中只允许出现一个NULL值,但在比较运算中认为NULL是不相等的,这点要注意;

 

(2)非唯一索引

表中索引列的值不唯一;

 

2.3、列个数分类

(1)复合索引

包含多个列的索引;

 

(2)单列索引

只包含一个列的索引。

 

2.4、特殊索引

(1)计算列索引

计算列上的索引;

 

(2)视图索引

对视图建立索引。

 

转自:http://blog.51cto.com/qianzhang/1217445