2.2 MySQL进阶篇:第二章_二.二_索引结构

2.2.1 概述

MySQL的索引是在存储引擎层实现的,不同的存储引擎有不同的索引结构,主要包含以下几种:

索引结构 描述
B+Tree索引 最常见的索引类型,大部分引擎都支持 B+ 树索引
Hash索引 底层数据结构是用哈希表实现的, 只有精确匹配索引列的查询才有效, 不支持范围查询
R-tree(空间索引) 空间索引是MyISAM引擎的一个特殊索引类型,主要用于地理空间数据类型,通常使用较少
Full-text(全文索引) 是一种通过建立倒排索引,快速匹配文档的方式。类似于Lucene,Solr,ES

上述是MySQL中所支持的所有的索引结构,接下来,我们再来看看不同的存储引擎对于索引结构的支持情况。

索引 InnoDB MyISAM Memory
B+Tree索引 支持 支持 支持
Hash索引 不支持 不支持 支持
R-tree(空间索引) 不支持 支持 不支持
Full-text(全文索引) 5.6版本之后支持 支持 不支持

注: 我们平常所说的索引,如果没有特别指明,都是指B+树结构组织的索引。

2.2.2 二叉树

假如说MySQL的索引结构采用二叉树的数据结构,比较理想的结构如下:

如果主键是顺序插入的,则会形成一个单向链表,结构如下:

所以,如果选择二叉树作为索引结构,会存在以下缺点:

  • 顺序插入时,会形成一个链表,查询性能大大降低。
  • 大数据量情况下,层级较深,检索速度慢。

我们也可以选择红黑树,红黑树是一颗自平衡二叉树,那这样即使是顺序插入数据,最终形成的数据结构也是一颗平衡的二叉树,结构如下:

但是,即使如此,由于红黑树也是一颗二叉树,所以也会存在一个缺点:

  • 大数据量情况下,层级较深,检索速度慢。

所以,在MySQL的索引结构中,并没有选择二叉树或者红黑树,而选择的是B+Tree,那么什么是B+Tree呢?在详解B+Tree之前,先来介绍一个B-Tree。

2.2.3 B-Tree

B-Tree,B树是一种多叉路衡查找树,相对于二叉树,B树每个节点可以有多个分支,即多叉。以一颗最大度数(max-degree)为5(5阶)的b-tree为例,那这个B树每个节点最多存储4个key,5个指针:

注: 树的度数指的是一个节点的子节点个数。

可以通过一个数据结构可视化的网站来简单演示一下:https://www.cs.usfca.edu/~galles/visualization/BTree.html

插入一组数据: 100 65 169 368 900 556 780 35 215 1200 234 888 158 90 1000 88 120 268 250 。然后观察一些数据插入过程中,节点的变化情况

特点:

  • 5阶的B树,每一个节点最多存储4个key,对应5个指针。
  • 一旦节点存储的key数量到达5,就会裂变,中间元素向上分裂。
  • 在B树中,非叶子节点和叶子节点都会存放数据。

2.2.4 B+Tree

B+Tree是B-Tree的变种,我们以一颗最大度数(max-degree)为4(4阶)的b+tree为例,来看一下其结构示意图:

我们可以看到,两部分:

  • 绿色框框起来的部分,是索引部分,仅仅起到索引数据的作用,不存储数据。
  • 红色框框起来的部分,是数据存储部分,在其叶子节点中要存储具体的数据。

B+Tree 与 B-Tree相比,主要有以下三点区别:

  • 所有的数据都会出现在叶子节点。
  • 叶子节点形成一个单向链表。
  • 非叶子节点仅仅起到索引数据作用,具体的数据都是在叶子节点存放的。

上述我们所看到的结构是标准的B+Tree的数据结构,接下来,我们再来看看MySQL中优化之后的B+Tree。

MySQL索引数据结构对经典的B+Tree进行了优化。在原B+Tree的基础上,增加一个指向相邻叶子节点的链表指针,就形成了带有顺序指针的B+Tree,提高区间访问的性能,利于排序。

2.2.5 Hash

MySQL中除了支持B+Tree索引,还支持一种索引类型---Hash索引。

1). 结构

哈希索引就是采用一定的hash算法,将键值换算成新的hash值,映射到对应的槽位上,然后存储在hash表中。

如果两个(或多个)键值,映射到一个相同的槽位上,他们就产生了hash冲突(也称为hash碰撞),可以通过链表来解决。

2). 特点

A. Hash索引只能用于对等比较(=,in),不支持范围查询(between,>,,...)

B. 无法利用索引完成排序操作

C. 查询效率高,通常(不存在hash冲突的情况)只需要一次检索就可以了,效率通常要高于B+tree索引

3). 存储引擎支持

在MySQL中,支持hash索引的是Memory存储引擎。 而InnoDB中具有自适应hash功能,hash索引是InnoDB存储引擎根据B+Tree索引在指定条件下自动构建的。

思考: 为什么InnoDB存储引擎选择使用B+tree索引结构?

1. 相对于二叉树,层级更少,搜索效率高;
2. 对于B-tree,无论是叶子节点还是非叶子节点,都会保存数据,这样导致一页中存储
的键值减少,指针跟着减少,要同样保存大量数据,只能增加树的高度,导致性能降低;
3. 相对Hash索引,B+tree支持范围匹配及排序操作;

MySQL进阶篇:详解索引结构的更多相关文章

  1. MySQL进阶篇(02):索引体系划分,B-Tree结构说明

    本文源码:GitHub·点这里 || GitEE·点这里 一.索引简介 1.基本概念 首先要明确索引是什么:索引是一种数据结构,数据结构是计算机存储.组织数据的方式,是指相互之间存在一种或多种特定关系 ...

  2. Scala进阶之路-Scala函数篇详解

    Scala进阶之路-Scala函数篇详解 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.传值调用和传名调用 /* @author :yinzhengjie Blog:http: ...

  3. 如何查看mysql数据库的引擎/MySQL数据库引擎详解

    一般情况下,mysql会默认提供多种存储引擎,你可以通过下面的查看: 看你的mysql现在已提供什么存储引擎:mysql> show engines; 看你的mysql当前默认的存储引擎:mys ...

  4. MySQL 执行计划详解

    我们经常使用 MySQL 的执行计划来查看 SQL 语句的执行效率,接下来分析执行计划的各个显示内容. EXPLAIN SELECT * FROM users WHERE id IN (SELECT ...

  5. Mysql加锁过程详解(9)-innodb下的记录锁,间隙锁,next-key锁

    Mysql加锁过程详解(1)-基本知识 Mysql加锁过程详解(2)-关于mysql 幻读理解 Mysql加锁过程详解(3)-关于mysql 幻读理解 Mysql加锁过程详解(4)-select fo ...

  6. Mysql加锁过程详解(1)-基本知识

    Mysql加锁过程详解(1)-基本知识 Mysql加锁过程详解(2)-关于mysql 幻读理解 Mysql加锁过程详解(3)-关于mysql 幻读理解 Mysql加锁过程详解(4)-select fo ...

  7. Mysql加锁过程详解(7)-初步理解MySQL的gap锁

    Mysql加锁过程详解(1)-基本知识 Mysql加锁过程详解(2)-关于mysql 幻读理解 Mysql加锁过程详解(3)-关于mysql 幻读理解 Mysql加锁过程详解(4)-select fo ...

  8. MySQL数据库优化详解(收藏)

    MySQL数据库优化详解 mysql表复制 复制表结构+复制表数据mysql> create table t3 like t1;mysql> insert into t3 select * ...

  9. Mysql 三大特性详解

    Mysql 三大特性详解 Mysql Innodb后台线程 工作方式 首先Mysql进程模型是单进程多线程的.所以我们通过ps查找mysqld进程是只有一个. 体系架构 InnoDB存储引擎的架构如下 ...

  10. 【目录】mysql 进阶篇系列

    随笔分类 - mysql 进阶篇系列 mysql 开发进阶篇系列 55 权限与安全(安全事项 ) 摘要: 一. 操作系统层面安全 对于数据库来说,安全很重要,本章将从操作系统和数据库两个层面对mysq ...

随机推荐

  1. Java 魔法值处理的四种方法

    Java 魔法值处理方案 魔法值的定义 方法一 静态常量(不推荐) 方法二 接口中定义 方法三 定义在实体类 方法四 使用枚举类 enum 总结 魔法值的定义 魔法值是Java中突兀出现在代码中的常量 ...

  2. python包引用方式总结

    本文为博主原创,转载请注明出处: 在Python中,有多种引用包的方式.以下是常见的方式: 1. import语句 import语句是最常见和推荐的引用包的方式.它允许你引入整个包或包中的特定模块/子 ...

  3. MySQL高级SQL语句

    MySQL高级SQL语句 围绕两张表 Location表 Store_Info表  #select选择  SELECT Store_Name FROM Store_Info;  #distinct去重 ...

  4. 欢迎来到hitcorgi,corgi居然被抢注了

    1 #include <iostream> 2 3 using namespace std; 4 5 int main() 6 { 7 cout << "Hello ...

  5. 一张图搞懂sql执行顺序

    冲浪时发现一张很有意思的图,细分了一个长sql语句的执行顺序

  6. 如何深度学习Python?

    安装必要软件:首先需要安装Anaconda或Miniconda等科研计算环境,并创建虚拟环境以便管理不同项目所需库和版本.可以按照如下步骤进行操作: 下载并安装 Anaconda 或 Minicond ...

  7. 根据子节点ID获取结构树中该子节点的所有父节点ID

    数据源: let adreeJson = [{ cat_id: 1, cat_name: '大家电', cat_pid: 0, cat_level: 0, cat_deleted: false, ch ...

  8. Android学习day04【Button】

    出现的一些小状况: 小状况 报错,代码显示运行成功 但是无法在模拟机上显示 原因是没有在包含应有id 其二是关于设置背景颜色中 关于background与backgroundTint的区别 //这是b ...

  9. 黑客玩具入门——9、Burp Suite

    Burp Suite是一款集成化的渗透测试工具,包含了很多功能,可以帮助我们快速完成对web应用程序的渗透测试和攻击.Burp Suite是由Java语言编写,因为Java是可以跨平台的,所以Burp ...

  10. Java八股面试整理(4)

    34.遇到过异常吗,如何处理? 在Java中,可以按照如下三个步骤处理异常: 捕获异常 将业务代码包裹在try块内部,当业务代码中发生任何异常时,系统都会为此异常创建一个异常对象.创建异常对象之后,J ...