赞
踩
数据库我们使用频率最高的,就是数据的查找了,怎么看一个查找的效果好不好呢?那当然是查找速率了,以及空间的占用。即时间和空间两个的复杂度都要低,那才称得上是一个好的数据库。
谈到查找,我们最普通的想法就是遍历,一个一个找下去,把所有的数据都找完了,不就找到了吗,可是这很不 amazing,速度太慢了,数据库中记录一多,查找效率就很慢,那么MySQL是如何解决这个问题的呢?
MySQL中InnoDB数据库引擎通过建立索引来维持高效的查找。
MySQL中记录是存放到页中的,一个页中有多条记录,页与页之间通过一个双向链表进行连接,每个页的File Header中都有一部分存储上一个页的页号和下一个页的页号,都是占用4字节。
先不要着急记录中的字段结构,下面我们会进行讲解。
谈到这个问题,我们先来了解以下普通的查找思路,正如我们上边所说,就是一个页面一个页面的找呗,好,我们就一个一个找。
一个页总共空间是16KB
),我们可以选择顺序查找,一条记录一条记录的找,那还有没有更好的方法呢,有,就是二分,但是这是有使用条件的啊,就是如果你是根据主键进行查找时,可以采用二分法快速定位到对应的位置,因为记录是按照主键大小顺序进行存储的,但如果你不是根据主键进行查找的呢,那就么的办法了,只能一个一个的找了呗,可想而知,是多么耗时。查找只需要两步。
很舒服的是这两步都能通过建立索引把时间复杂度缩短到O(n)以下,是不是很舒服,既然效率高,建立索引,何乐而不为呢。
MySQL中的索引主要是B+树索引,当然也有哈希索引,但我们讲的是主要。
建立索引相当于为数据页编写了一个字典目录,通过目录我们能够很快的查找到页的位置,然后再找到记录的位置。
想一想,我们要想实现二分类似的快速查找,我们得先把页号提取出来吧,索引就是干了个这事,索引通过将页号不断提取出来,最终形成一颗树一样的多层次结构,这种结构就是B+树。
B+树有以下一些规则:
根据其规则,我们能够画出MySQL中B+树索引的结构,如下:
我们来解释以下这棵神奇的树
每个页中最上面那个蓝色的方框是代表啥呢,蓝色方框所指的是上面我们所说的记录结构的record_type字段,其值可以取0,1,2,3。0代表是普通记录,也就是存放实际数据的记录。1表示B+树非叶子节点记录。2表示最小记录,3表示最大记录。
第二个蓝色方框代表啥呢,第二个蓝色方框所指的是记录结构中的next_record字段,其中存放了从当前记录的真实数据到下一条记录的真实数据的地址偏移量。说人话也就是,通过这个我们可以找到下一条记录。
第三个橙色方框中存放的是建立数据表是所设定的主键的值,如果没有指定主键的话,数据库会自动指定主键。
非叶子节点中的绿色方框很明显就是指子节点的页号啊。
剩下的深蓝色和红色方框中存放的就是实际的数据了,当然那个橙色方框中的主键也是数据项。
效果怎么样,试试就知道
又是这个图,我们试一下查找,假如我们要查找主键为220的记录,加上索引后,我们的查找为页33 -> 页30 -> 页9,通过三次我们就找到了所需要记录所存放的页号,之后再在页中进行二分查找就能找到了,是不是很快。相比遍历那种比较笨的方法,效果就非常好了。
上面我们所说的数据存放于叶子节点的就是聚簇索引。
B+树中的数据是按照主键顺序进行排序的,但是如果我们的查找条件并不是按照主键的呢。这时我们的索引就没用了,一个想法就是为每个属性建立一颗B+树,这当然可以,但是太浪费了吧,一份数据存有好几份,这真的是太浪费存储空间了,我们怎么做呢,我们为其他非主键属性建立一个二级索引。
与聚簇索引不同的有以下几点(假如我们根据 c 查找到记录,c 不是主属性):
页内的记录是按照 c 列的大小顺序排成的一个单向链表
存放用户记录的页也是根据页中记录的 c 列大小顺序排成一个双向链表
存放目录项记录的页在同一层次上页与页之间按照 c 列的大小顺序通过双向链表进行连接
B树的叶子节点存储的不是完整的用户记录,而是 c 列 + 主键这两个列的值
目录项记录不是主键 + 页号,而是 c 列 + 页号
二级索引的查找过程:
MyISAM也是用树形结构,但是将索引和数据分开存储。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。