看了很多关于索引的博客,讲的大同小异。但是始终没有让我明白关于索引的一些概念,如B-Tree索引,Hash索引,唯一索引....或许有很多人和我一样,没搞清楚概念就开始研究B-Tree,B+Tree等结构,导致在面试的时候答非所问!本文中有关存储引擎请查看MySQL存储引擎-InnoDB和MyISAM

索引是什么?

索引是帮助MySQL高效获取数据的数据结构。

索引能干什么?

提高数据查询的效率。

索引:排好序的快速查找数据结构!索引会影响where后面的查找,和order by 后面的排序。

一、索引的分类

1️⃣从存储结构上来划分:BTree索引(B-Tree或B+Tree索引),Hash索引,full-index全文索引,R-Tree索引。

2️⃣从应用层次来分:普通索引,唯一索引,复合索引

3️⃣根据中数据的物理顺序与键值的逻辑(索引)顺序关系:聚集索引,非聚集索引。

​ 1️⃣中所描述的是索引存储时保存的形式,2️⃣是索引使用过程中进行的分类,两者是不同层次上的划分。不过平时讲的索引类型一般是指在应用层次的划分。

就像手机分类:安卓手机,IOS手机 与 华为手机,苹果手机,OPPO手机一样。

普通索引:即一个索引只包含单个列,一个表可以有多个单列索引

唯一索引:索引列的值必须唯一,但允许有空值

复合索引:即一个索引包含多个列

聚簇索引(聚集索引):并不是一种单独的索引类型,而是一种数据存储方式。具体细节取决于不同的实现,InnoDB的聚簇索引其实就是在同一个结构中保存了B-Tree索引(技术上来说是B+Tree)和数据行。

非聚簇索引:不是聚簇索引,就是非聚簇索引(认真脸)。

二、索引的底层实现

mysql默认存储引擎innodb只显式支持B-Tree( 从技术上来说是B+Tree)索引,对于频繁访问的表,innodb会透明建立自适应hash索引,即在B树索引基础上建立hash索引,可以显著提高查找效率,对于客户端是透明的,不可控制的,隐式的。

不谈存储引擎,只讨论实现(抽象)

Hash索引

基于哈希表实现,只有精确匹配索引所有列的查询才有效,对于每一行数据,存储引擎都会对所有的索引列计算一个哈希码(hash code),并且Hash索引将所有的哈希码存储在索引中,同时在索引表中保存指向每个数据行的指针。

B-Tree索引(MySQL使用B+Tree)

​ B-Tree能加快数据的访问速度,因为存储引擎不再需要进行全表扫描来获取数据,数据分布在各个节点之中。

B+Tree索引

​ 是B-Tree的改进版本,同时也是数据库索引索引所采用的存储结构。数据都在叶子节点上,并且增加了顺序访问指针,每个叶子节点都指向相邻的叶子节点的地址。相比B-Tree来说,进行范围查找时只需要查找两个节点,进行遍历即可。而B-Tree需要获取所有节点,相比之下B+Tree效率更高。

结合存储引擎来讨论(一般默认使用B+Tree)

案例:假设有一张学生表,id为主键

id name birthday
1 Tom 1996-01-01
2 Jann 1996-01-04
3 Ray 1996-01-08
4 Michael 1996-01-10
5 Jack 1996-01-13
6 Steven 1996-01-23
7 Lily 1996-01-25

在MyISAM引擎中的实现(二级索引也是这样实现的)

在InnoDB中的实现

三、问题

问:为什么索引结构默认使用B-Tree,而不是hash,二叉树,红黑树?

hash:虽然可以快速定位,但是没有顺序,IO复杂度高。

二叉树:树的高度不均匀,不能自平衡,查找效率跟数据有关(树的高度),并且IO代价高。

红黑树:树的高度随着数据量增加而增加,IO代价高。

问:为什么官方建议使用自增长主键作为索引。

结合B+Tree的特点,自增主键是连续的,在插入过程中尽量减少页分裂,即使要进行页分裂,也只会分裂很少一部分。并且能减少数据的移动,每次插入都是插入到最后。总之就是减少分裂和移动的频率。

插入连续的数据:

插入非连续的数据

原文地址:李强的个人博客(基于SSM,Nginx+Redis的后台架构)

图解MySQL索引--B-Tree(B+Tree)的更多相关文章

  1. 图解MySQL索引(二)—为什么使用B+Tree

    失踪人口回归,近期换工作一波三折,耽误了不少时间,从今开始每周更新~ 索引是一种支持快速查询的数据结构,同时索引优化也是后端工程师的必会知识点.各个公司都有所谓的MySQL"军规" ...

  2. 图解MySQL索引(上)—MySQL有中“8种”索引?

    关于MySQL索引相关的内容,一直是一个让人头疼的问题,尤其是对于初学者来说.笔者曾在很长一段时间内深陷其中,无法分清"覆盖索引,辅助索引,唯一索引,Hash索引,B-Tree索引--&qu ...

  3. 图解MySQL索引(三)—如何正确使用索引?

    MySQL使用了B+Tree作为底层数据结构,能够实现快速高效的数据查询功能.工作中可怕的是没有建立索引,比这更可怕的是建好了索引又没有使用到.本文将围绕着如何优雅的使用索引,图文并茂地和大家一起探讨 ...

  4. 深入理解MySQL索引底层数据结构

    作者:IT王小二 博客:https://itwxe.com MySQL 索引相关的数据结构有两种,一种是 B+tree,一种是 Hash,那么为什么在 99.99% 的情况下都使用的是 B+tree索 ...

  5. Mysql索引机制(B+Tree)

    1,索引谁实现的: 索引是搜索引擎去实现的,在建立表的时候都会指定,搜索引擎是一种插拔式的,根据自己的选择去决定使用哪一个. 2,索引的定义: 索引是为了加速对表中数据行的检索而创建的一种分散存储的( ...

  6. B-tree B+tree适合文件系统索引和MySQL索引

    B-树 B-树,这里的 B 表示 balance( 平衡的意思),B-树是一种多路自平衡的搜索树 它类似普通的平衡二叉树,不同的一点是B-树允许每个节点有更多的子节点.下图是 B-树的简化图. B-树 ...

  7. B+/-Tree原理(mysql索引数据结构)

    B+/-Tree原理 B-Tree介绍 B-Tree是一种多路搜索树(并不是二叉的):       1.定义任意非叶子结点最多只有M个儿子:且M>2:       2.根结点的儿子数为[2, M ...

  8. MySQL的索引为什么用B+Tree?InnDB的数据存储文件和MyISAM的有何不同?

    前言 这篇文章的题目,是我真实在面试过程中遇到的问题,某互联网众筹公司在考察面试者MySQL相关知识的第一个问题,我当时还是比较懵的,没想到这年轻人不讲武德,不按套路出牌,一般的问MySQL的相关知识 ...

  9. mysql索引 B+tree

    一.B+tree示意图 二.为什么要用索引 1.索引能极大减少存储引擎需要扫描的数据量:因为索引有序所以可以快速查找并且不用全表查找: 2.索引可以把随机IO变为顺序IO:因为B+tree在数据中保存 ...

随机推荐

  1. FFMPEG结构体分析:AVFrame

    注:写了一系列的结构体的分析的文章,在这里列一个列表: FFMPEG结构体分析:AVFrameFFMPEG结构体分析:AVFormatContextFFMPEG结构体分析:AVCodecContext ...

  2. 数据挖掘进阶之关联规则挖掘FP-Growth算法

    数据挖掘进阶之关联规则挖掘FP-Growth算法 绪 近期在写论文方面涉及到了数据挖掘,需要通过数据挖掘方法实现软件与用户间交互模式的获取.分析与分类研究.主要涉及到关联规则与序列模式挖掘两块.关联规 ...

  3. "《算法导论》之‘线性表’":基于静态分配的数组的顺序表

    首先,我们来搞明白几个概念吧(参考自网站数据结构及百度百科). 线性表 线性表是最基本.最简单.也是最常用的一种数据结构.线性表中数据元素之间的关系是一对一的关系,即除了第一个和最后一个数据元素之外, ...

  4. AndroidUI之绘图机制和原理 最完整的文章

    转载请标明出处:http://blog.csdn.net/sk719887916/article/details/39961171,作者:skay  导读: 熟悉javaGUI的朋友对java绘图必定 ...

  5. web报表工具FineReport的SQL编辑框的语法简介

    感谢大家捧场,这里继续分享关于SQL编辑框的一些语法心得总结,因为数据集定义的面板,也是FineReport报表中最常用的模块之一. 1.我理解的执行过程. 这里其实是生成一个字符串,FineRepo ...

  6. lpad函数

    函数介绍 lpad函数是Oracle数据库函数,lpad函数从左边对字符串使用指定的字符进行填充.从其字面意思也可以理解,l是left的简写,pad是填充的意思,所以lpad就是从左边填充的意思. 2 ...

  7. java多线程的基础-java内存模型(JMM)

    在并发编程中,需要处理两个关键问题:线程之间如何通信,以及线程之间如何同步.通信是指线程之间如何交换信息,在命令式编程中,线程之间的通信机制有两种:内存共享和消息传递.      同步是指程序中用于控 ...

  8. Java IO学习--(五)字节和字符数组

    内容列表 从InputStream或者Reader中读入数组 从OutputStream或者Writer中写数组 在java中常用字节和字符数组在应用中临时存储数据.而这些数组又是通常的数据读取来源或 ...

  9. decode ways(动态规划)

    A message containing letters from A-Z is being encoded to numbers using the following mapping: 'A' - ...

  10. java——封装和关键字

    封装:将类的属性和方法的实现细节隐藏起来的过程 封装的好处:1重用性(代码)2,利于分工3,隐藏细节 访问关键字:public private 默认访问修饰符,protected static关键字 ...