数据库索引-随笔
经常会对数据库索引有各种各样的疑问,有了问题会第一时间google一下,往往会找到些启发性的解释。但是,得到的东西太过零碎,难成系统。不成系统的知识,很难记忆,也很难对新问题的分析和解决产生帮助。因此,特将一些收获记录在这篇随笔中,以待日后拾遗!
首先要明确数据库索引是个什么东西?
数据库索引,是数据库管理系统中一个排序的数据结构,以协助快速查询、更新数据库表中数据。——维基百科
索引是对数据库表中一列或多列的值进行排序的一种结构,使用索引可快速访问数据库表中的特定信息。——百度百科
上面的定义很准确,反映了索引的一些特点。但是,似乎不能帮助我们对索引有一个直观的认识。不过,可以抓住索引的一个核心:排序。两个定义中都提到了排序,下面就通过一张图片直观地感受一下索引到底是怎样一种排序的数据结构。

对一些常用数据结构掌握比较牢靠的人应该已经看出,上图就是一个在磁盘上实现的B+树。利用左半边的Index部分,可以实现对数据的类二分查找(这里的类二分查找是我自己胡诌的一个词)。MySQL的InnoDB引擎在实现其索引时采用的就是这样的数据结构,索引段和数据段分开存放成两个文件。具体的InnoDB的数据存储结够参见[2]。
数据库的索引前可以加很多限定词,比如简单索引,唯一索引,聚合索引,复合索引等。
简单索引和唯一索引都好理解,对单列建立的索引就是简单索引。如果再加上一个限制条件,索引列的值必须唯一,那么就成了唯一索引。我一开始难以理解的是聚合索引和复合索引。特别是复合索引。
下面首先看看聚合索引具体是指什么类型的索引。
汉语字典的正文本身就是聚集索引的一部分。比如,我们要查“安”字,就会很自然地从字典的前几页开始找,因为“安”的拼音是“an”,而按照拼音排序的汉字字典中拼音以“a”开头的字自然排在最前面,那么“安”字就一定排在字典的前部。如果您翻完了所有以“a”开头的部分仍然找不到这个字,那么就说明您的字典中没有这个字;同样的,如果查“张”字,那您也会将您的字典翻到最后面,因为“张”的拼音是“zhang”。也就是说,字典的正文部分和目录有同样的排列顺序,您并不是一定需要查找目录来确定内容的位置。这种正文内容本身就是一种按照一定规则排列的索引称为“聚集索引”。
如果您认识某个字,您可以快速地从自动中查到这个字。但您也可能会遇到您不认识的字,不知道它的发音,这时候,您就不能按照刚才的方法找到您要查的字,而需要去根据“偏旁部首”查到您要找的字,然后根据这个字后的页码直接翻到某页来找到您要找的字。但您结合“部首目录”和“检字表”而查到的字的排序并不是真正的正文的排序方法,比如您查“张”字,我们可以看到在查部首之后的检字表中“张”的页码是672页,检字表中“张”的上面是“驰”字,但页码却是63页,“张”的下面是“弩”字,页面是390页。很显然,这些字并不是真正的分别位于“张”字的上下方,现在您看到的连续的“驰、张、弩”三字实际上就是他们在非聚集索引中的排序,是字典正文中的字在非聚集索引中的映射。我们可以通过这种方式来找到您所需要的字,但它需要两个过程,先找到目录中的结果,然后再翻到您所需要的页码。这种索引就是“非聚集索引”。
总的来说,如果数据段里面的数据和Index段中的顺序是一致的,那么这个索引就是聚集索引。因为数据只存一份,所以一张表也就只能有一个聚集索引。聚集索引因为数据部分是有序的,所以特别有利于范围查找。
接下来再看看什么是聚合索引。
和上面的聚合索引一样,我们先来看日常生活中的一个例子。电话簿前的目录是按人的姓名排序的。首先是按照姓排序(假设都是单姓),同样姓的人再按照名字部分的第一个字排序,以此类推。聚合索引是同样的概念。索引部分不再是按照单列的值来排序,而是对多个列的值按照左前缀的方式排序。理解了这些,也就不难知道为什么MySQL在仅在查询条件中的列满足聚合索引左前缀匹配的情况下采用索引优化了。
参考资料:
[1]http://www.cnblogs.com/flashicp/archive/2007/05/08/739245.html
[2]http://www.perfgeeks.com/?p=406
[3]http://www.cnblogs.com/KissKnife/archive/2009/03/30/1425534.html
浙公网安备 33010602011771号