您的位置:首页 > 理论基础 > 数据结构算法

原理:数据结构-索引 && 应用篇:MySQL索引背后的数据结构及算法原理详解

2014-09-06 23:26 603 查看
特点简介:

索引文件比数据文件小,可以有效地装载到内存。通过对内存索引文件的查找定位到记录,然后通过一次磁盘对象读取操作就可以获取到需要搜索的对象。

静态索引结构和动态索引结构啥区别?

我认为静态是指新节点的加入对原有的索引结构不会发生改变,比如:稠密索引直接把新节点加到数组的后面;倒排表新次关键码的加入直接加到次关键码列表的后面,已有次关键码添加新对象,只要在次关键码对象链表中加入新对象地址指针即可。而作为典型动态索引结构的B树,新索引节点的加入为了保持搜索树的平衡性,可能需要调整树的结构以满足平衡性。

1、静态索引结构

1)、线性索引 (主键索引)(索引数组存储)

稠密索引:

一个索引项对应数据表中的一个对象。当对象在外存中按添加的顺序而不是按关键码有序存放的时候必须采用稠密索引。

稀疏索引(索引顺序结构):

数据对象在外存中按关键码(主键)分块有序存放,每个子块中的对象可以是有序,也可以是无序,有序的话子块中可以使用折半查找,提高查找速度,但是添加记录也会慢些。

对索引顺序结构进行查找时,根据关键码先在索引中定位对象所在的数据子块,然后在子块中定位查找的对象。

2)、倒排表

主键索引能唯一地标识对象,也叫主索引。主键只有一个,日常应用中也需要对其它熟悉列进行搜索,所有,除了主关键码外,也有必要把其它常用的搜索属性设定为次关键码,建立次索引表。次索引列因为属性值不是唯一的,所以在次索引中,建立一个所有值的一个列表,对每个取值建立一个具有相同属性值的对象的存放有序或主键有序的顺序链表。次索引中存放对象地址的指针可以用主键来表示,这样在非主键属性列查找中,可以先在次索引中查找到对象主键,然后在主键索引中找到对象的地址。

3)、m路静态搜索树(多级索引)

m路搜索树:

当数据量很庞大的时候,索引块也会非常大,一次性无法读入所有的索引块到内存,这个时候就要考虑多级索引,最高一级的索引常驻内存就可以了,每一级中的字索引块有自己最大主关键码值。多级索引中,每个索引块大小一样,每个索引块最大存放m个索引项,每个索引项给出各子树节点最大关键码和存放地址,这样形成了m叉树,这种利用m叉树实现的多级索引,就是m路搜索树。m叉树中m意思是每个索引块中最大存放的索引项数目,跟索引级数没有关系。m叉树中叶节点中个索引项给出数据表中对象的关键码和存放地址。

2、动态索引结构(动态m路搜索树)

动态调整的目的一般就是保持搜索树的平衡性。

1)、B树

定义可以参考书籍,说说和B+树的理解和定义中不明确的地方,B树中每个节点包含了键值和键值对于的数据对象存放地址指针,所以成功搜索一个对象可以不用到达树的叶节点。成功搜索包括节点内搜索和沿某一路径的搜索,成功搜索时间取决于关键码所在的层次以及节点内关键码的数量。在B树中查找给定关键字的方法是:首先把根结点取来,在根结点所包含的关键字K1,…,kj查找给定的关键字(可用顺序查找或二分查找法),若找到等于给定值的关键字,则查找成功;否则,一定可以确定要查的关键字在某个Ki或Ki+1之间,于是取Pi所指的下一层索引节点块继续查找,直到找到,或指针Pi为空时查找失败。

2)、B+树

B树的变种。B+树非叶节点中存放的关键码并不指示数据对象的地址指针,非也节点只是索引部分。所有的叶节点在同一层上,包含了全部关键码和相应数据对象的存放地址指针,且叶节点按关键码从小到大顺序链接。如果实际数据对象按加入的顺序存储而不是按关键码次数存储的话,叶节点的索引必须是稠密索引,若实际数据存储按关键码次序存放的话,叶节点索引时稀疏索引。B+树有2个头指针,一个是树的根节点,一个是最小关键码的叶节点。

所以 B+树有两种搜索方法:

一种是按叶节点自己拉起的链表顺序搜索。

一种是从根节点开始搜索,和B树类似,不过如果非叶节点的关键码等于给定值,搜索并不停止,而是继续沿右指针,一直查到叶节点上的关键码。所以无论搜索是否成功,都将走完树的所有层。B+ 树中,数据对象的插入和删除仅在叶节点上进行。

这两种处理索引的数据结构的不同之处:

Ø B树中同一键值不会出现多次,并且它有可能出现在叶结点,也有可能出现在非叶结点中。而B+树的键一定会出现在叶结点中,并且有可能在非叶结点中也有可能重复出现,以维持B+树的平衡。

Ø 因为B树键位置不定,且在整个树结构中只出现一次,虽然可以节省存储空间,但使得在插入、删除操作复杂度明显增加。B+树相比来说是一种较好的折中。

Ø B树的查询效率与键在树中的位置有关,最大时间复杂度与B+树相同(在叶结点的时候),最小时间复杂度为1(在根结点的时候)。而B+树的时候复杂度对某建成的树是固定的。

3,hash索引

hash索引只支持精确查找,不支持范围查找。hash算法函数有可能不能保证哈希值的唯一性,即使是crc32这样的函数。所以可能有哈希碰撞问题(不同的串得到相同的hash值),md5()和sha1()是强加密函数,不会产生哈希碰撞。

参考文献:http://blog.sina.com.cn/s/blog_798f21a00100x6du.html

MySQL索引背后的数据结构及算法原理(很详细,图文并茂)

参考资料:http://blog.codinglabs.org/articles/theory-of-mysql-index.html
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: