目录
一、什么是索引
1.1索引的原理
1.2索引的优缺点
二、索引的使用
2.1查看索引
2.2手动创建索引
2.3删除索引
三、MySQL索引底层的数据结构
3.1 B树
3.2 B+树
一、什么是索引
索引是一种特殊的文件,包含着对数据表里所有记录的引用指针。可以对表中的一列或多列创建索引,并指定索引的类型,各类索引有各自的数据结构实现。
通俗来说,索引就是一本字典的的查询目录,用以加快查询的速度
1.1索引的原理
数据库的索引是以列为维度建立的,由于数据库有很多列,所以索引也可以有很多
- 索引是存储在数据库服务器的硬盘上, 具体来说, 是存储在硬盘上的文件中的.
因为数据库中存储的数据量很大, 所以我们才会想去建立索引, 以便于在查询的时候快速锁定指定数据. 而基于这些庞大的数据量建立起来的索引本身也很大, 而且一般还会建立多个不同的索引.所以, 索引不可能全部存储在内存中.
- 索引采取的是空间换取时间
- 没有建立索引就是默认的全文检索
1.2索引的优缺点
缺点:
- 需要额外的数据库硬盘空间
- 有可能拖慢数据库 增删改 的速度. 进行 增删改 的时候, 不仅是要改变数据库中的数据, 还要更改维护索引文件.(但是日常的工作中增删改是比较少的)
- 维护索引需要消耗数据库资源.
优点:
- 大大提高数据查询速度.
- 减少硬盘IO次数
二、索引的使用
2.1查看索引
show index from tb_name; --tb_name是自定义的表名
- 首先创建一个基本表,在查看具体的索引,这里是没有索引的
- 删除当前的表再次进行创建,这一次添加主键约束,发现数据库会自动创建一个名PRIMARY的索引(原因是主键不允许重复,因此进行插入或者修改就需要先查询,这个过程相对复杂所以就会自动创建一个索引来加快查询)
- 再次删除,这一次添加unique的约束条,同样的也会自动创建一个索引,这里的索引命名就是以列名命名的
- 再次删除表,这一次添加主键约束以及外键约束,这里发现建立外键约束也会自动创建索引,并且索引是不唯一的。
通过上述示例,MySQL数据库中关于主键约束、unique约束、外键约束是会自动生成索引的
2.2手动创建索引
create index 索引名 on 表名(字段名);
手动创建索引是存在一定的风险的,因为在创建索引的过程中数据库是不可用的,而且当数据量很大的时候,索引的创建也可能会失败甚至会导致数据库卡死。所以正确的索引创建是在建表之的时候
当确实需要在大量数据的基础之上去创建索引,这里的方法是将表中的数据进行备份,准备好一个新的mysql服务器,然后创建好新的表以及索引,最后将需要替换的mysql的服务器关闭,最后将新的mysql服务器替换上去就行了。
2.3删除索引
drop index 索引名 on 表名;
在删除索引的时候也需要主要当有外键约束的主表时,先要将外键约束的表进行删除,这与删除表的道理是一样的,子表对父表也有一个约束作用。
三、MySQL索引底层的数据结构
为了了解清楚MySQL底层的数据结构,取决于MySQL使用哪个存储引擎,当前主流的的储存引擎是Innodb,并且这里的数据结构是在硬盘上的。接下将以Innodb来展开
索引是为了进行快速的查找,所以在数据结构的选取的时候不免就会想到哈希表、二叉搜索树,但是在数据库中是有模糊查询与范围查询的,哈希表、二叉搜索树这些数据只能进行精确的查询所以这两个数据结构是无法实现的,进而又想到了红黑树,但是红黑树的时间复杂度O(logn)当树的深度越深的时候查询效率越慢,虽然这个在内存中没有很大的影响,但是数据库中的数据结构是放在硬盘上的,这样会导致查询效率大大降低!所以这里就有了数据库的数据结构:B树以及B+树
3.1 B树
B树的核心思路和“二叉搜索树”是差不多的,但是为了降低树的高度,B树采取的是N叉树,这样就大大降低了树的高度以及节点数。为什么要去降低树的高度?
因为MySQL的数据是存储在硬盘文件中的,查询处理数据时,需要先把硬盘中的数据加载到内存中,硬盘IO操作非常耗时,所以节点越多、树的高度越高,硬盘的IO操作就越多。这样的查询效率就会大大降低。
B树的主要特点有:
- B树的节点中存储着多个元素, 每个内节点有多个分叉.
- 在所有的节点中都存储数据
- 父节点当中的元素不会出现在子节点中.
- 所有的叶子节点都位于同一层, 叶子节点具有相同的深度, 叶子节点之间没有指针连接.
B树结构大致如下:
虽然B树已经很理想了, 但是还有可以优化的地方:
- B树不支持范围查询的快速查找. 例如: 仍然根据上图, 我们想要查询10到35之间的数据, 查找到10之后, 需要回到根节点重新遍历查找, 需要从根节点进行多次遍历, 查询效率有待提高.
- B树的复杂度很不稳定. 与 key 在树中的位置有关, 最好的时间复杂度为O(1)
由于B树存在一定的不足,数据库中就引入了B+树
3.2 B+树
B+树是B树的改造版, 他与B树的不同点有:
- 叶子节点存储的是数据的全集, 其他节点不再存储data, 只存储key
- 叶子节点之间使用双向指针连接, 最底层的叶子节点形成了一个双向有序链表, 方便进行范围查询.
B+树的大致结构:
由于B+树将所有的索引项都放在了叶子节点上, 所以每次查询数据的时候, 都需要检索到叶子节点, 那么每次检索的硬盘IO次数与树的高度产生了直接的关系, 并且查询的时间复杂度更为稳定.
但是由于非叶节点不再存放data,一次硬盘IO操作能够读取更多的key, 能索引的范围更大更精确, 所以相对于B树来说, B+树的树高理论情况下是比B树要矮的, 进而可以减少相应的硬盘IO操作.
MySQL数据库中innodb搜索引擎使用的就是B+树