一、索引
索引介绍
索引就相当于一本书的目录(index
),比如我们如果想要快速查找到书中的某一部分内容,我们就可以查看索引来找到我们指定的内容。
而在MySQL中,表中存储的数据是非常庞大的,最基本的方式就是把表中的数据进行一条一条的进行遍历,但是这样的遍历方式的速度太慢了,因为数据库中的信息量是非常庞大的。所以,我们就需要给数据库中的表建立一个索引(建立索引的方式是按照列的维度进行建立的
)来提高我们的查找速度。
MySQL中索引的使用
查看索引
举个栗子3测试数据的sql语句:
create table classes(classes_Id int primary key,name varchar(20));
create table student(id int primary key,name varchar(20),classes_Id int,foreign key (classes_Id) references classes(classes_Id));
// 查看索引
show index from classes;
show index from student;
上述三种情况:主键
、unique
、外键
都会使表自动创建出索引。所以此时我们就不需要再对单独的这一列创建单独的索引了。
创建索引(危险危险)
手动给指定的列创建索引语法格式:create index 索引名 on 表名(字段名);
删除索引(比较危险)
删除索引只能删除手动创建的索引。
删除索引这个操作也是比较危险的,不能轻易删除索引。
假设有这样一个场景:现在我们有一个有很多很多数据的表,同时这个数据库此时是处于生产环境的一个数据库。但是我们现在必须要创建删除索引。此时怎么办呢?我们要知道数据库服务器往往不仅仅是单台服务器,为了整个系统的稳定性,通常会搞出多个mysql服务节点,这些节点的数据往往都是一样的,能够提出相同的服务。
(以防万一某个mysql服务器节点挂了,而其它服务器依然可以很正常运行
)
此时我们可以这样做:先准备好一个新的mysql服务器,把表和索引都创建好,然后把数据都导过来,再把要替换的mysql服务器关闭掉,然后再把新的mysql服务器替换掉就好了。
二、索引底层数据结构
MySQL底层的数据结构并不是一个定式,而是取决于MySQL使用哪个存储引擎。
在MySQL中的Innodb存储引擎中,索引的底层数据结构是B+树
;而在其它存储引擎中,也可能会用到hash索引,此时就只能应对精准匹配查询的这种情况(所以hash并不是不能作为索引,只是丧失了部分功能而已)。
想要清楚什么是B+树,我们就需要先知道什么是B - 树
。
B-树
B - 树(本质是N叉搜索树
):B 树的一个节点上可以保存多个key
,N个key
就可以延伸出N+1
个分支。查找元素的流程就是拿着要查找的元素从根节点出发(判断要查找的元素是否在根节点上),如果不存在的话,我们就需要看看这个元素最终落到哪个区间内,然后沿着这个区间的路线继续往后找,如果最终的叶子节点依然不存在我们要查找的元素,那么这个要查找的元素就真的不存在了。
与二叉搜索树相比,B - 树
的每个节点可以存储多个元素,在元素总个数相同的情况下,B - 树
的节点数和高度都会大大降低;同时B - 树
在同一个层次中会存在多个分叉,这也会降低节点数和树的高度。
对于数据库来说,每个节点上的数据都需要从数据库中读取出来才能进行比较(每个节点访问的时候都会进行硬盘的IO操作。)随着B树的节点减少的同时,节点的访问次数就会减少,硬盘IO操作也当然会随之减少。还有一点我们需要知道:一个节点中有一个key和一个节点中有多个key的节点访问时的硬盘IO操作的开销是差不多的。
B+树
好了,现在我们来了解下数据库中索引的主角:B+树(N叉搜索树)。B+树在B树的基础上又做出了一些改进。
B+树特点:
- N个key分出了N个区间,每个节点上的最后一个key就是最大值(也可能是第一个key,即最小值)。
- 父节点中的key会在子节点中重复出现(以最大值或者最小值的身份),这样就会出现一个效果,即叶子节点这一层的的数据包含了整个数据的全集。
- 把叶子节点进行链表方式的首尾相连,此时叶子节点这样的一个连接方式就可以快速找到上一个或者下一个节点,方便进行范围查询(只要能确定开头和结尾,开头和结尾中间的子链表就是我们查询出来的结果)。
好了,以上就是本文的全部内容,就到这里吧!!!再见啦友友们~~~
三、索引总结
好了,现在再来重新回顾一下索引吧!!!
索引简单点来说就相当于一本书中的目录,可以加快我们的查找速度。并且索引是按照列来进行查询的。
索引的优劣:
- 优点:提高查询速度。
- 缺点:占据额外的内存空间。一定程度上会拖慢插入修改删除数据的速度。
索引具体的使用方式:
- 创建索引:会自动创建的索引:
主键
、外键
、unique
。手动创建索引语法格式:create index 索引名称 on 表名(列名);
- 查看索引:
show index from 表名;
- 删除索引:
drop index 索引名 on 表名;
索引的数据结构:
- hash不适合作为索引的数据结构,原因是因为hash不能够进行范围查询,不能够进行模糊匹配查询。
- 红黑树也不适合作为索引的数据结构,虽然红黑树可以进行范围查询,但是需要引入更多的
硬盘IO操作
。 B+树就非常适合索引的数据结构
,在MySQL中的Innodb存储引擎中的索引就是以B+树作为底层数据结构的。
B+树的优势:
- B+树非常擅长范围查询,即只要找到开头和结尾,那么中间那一部分的链表就是我们要查找的数据。
- 所以的查询操作的查询时间非常稳定,因为所有的查询操作最终都会落在叶子节点上。而B树的话有点数据可能在根节点找到,有的数据可能在叶子节点找到,这样的话查询速度就很不稳定。(某些时候,稳定比快速更加重要)
- 由于叶子节点上是完整的数据全集,因此表的每一行数据的其它列都可以保存在叶子节点上(我们要知道物理结构中并不存在
表格
这样的数据结构,所以我们可以使用B+树来存储表中的数据,表格只是看起来像一个表格而已
),而非叶子节点只存储构建索引的key即可(ID)。此时非叶子节点的存储空间是非常小的以至于我们可以在内存中缓存一份,这样的话在进行数据查询的时候就可以通过内存来直接进行数据的比较,从而更快速的找到叶子节点上的记录(这里又进一步的减少了硬盘IO操作的次数
)。而B树的话由于B树的整个数据的全集并非只有叶子节点,非叶子节点也有可能是数据的全集。 - B树如果也要把元素存储到每个节点上,非叶子节点所占用的空间就会变大,从而无法在内存中进行缓存了。当然对应的硬盘IO操作也会增多。
嗯,本文就到这里吧,再见啦友友们!!!
记得一键三连哦!!!