精华内容
下载资源
问答
  • MySQL底层索引数据结构

    千次阅读 2017-08-30 17:16:54
    为什么MySQL索引数据结构要选用B Tree 、 B+Tree来实现? 我们来对比一下其他的数据结构: 常见的几种类型:  hash 二叉树  红黑树   索引效率的评价标准是IO次数 局部性原理: 空间上...

    一、索引是什么?

    索引是帮助我们高效获取数据的数据结构(为了寻址更快)

    索引是一个文件

     

     

    二、索引的数据结构(B Tree  、 B+Tree)

    为什么MySQL索引数据结构要选用B Tree  、 B+Tree来实现?

    我们来对比一下其他的数据结构:

    常见的几种类型:

        hash

    二叉树

      红黑树

     

    索引效率的评价标准是IO次数

    局部性原理:

    空间上局部性原理:读取时会把一块全部读取

    时间上的局部性原理:读取完数据存储在换成,方便你下一次再读取

     

    (红黑树)

    二叉树、红黑树的树的高度是不限的,并且每个节点只有一条数据,那么要查找某些数据的时候会执行很多次IO

     

    (B+Tree)

    B+Tree只有最下面的叶子节点才是它的数据,每个节点可以多条数据,查找1是执行3次IO,查找2同样也是执行3次IO ,MySQL查询数据最多IO次数3-5次(当然数据量越大,树的高度也会增长,IO也会增加)

     

     

     

    描述的很粗糙望指正。

     

     

     

     

     

     

     

     

     

     

    展开全文
  • 掌握数据结构,就可以掌握索引的底层原理,我们应当有**路漫漫其修远兮,吾将上下而求索**的态度,本文将探究索引数据结构以及MySQL使用的是哪种,话不多说直接发车! 索引数据结构 Markdown排版利器,支...

    点赞多大胆,就有多大产!开源促使进步,献给每一位技术使用者和爱好者!
    干货满满,摆好姿势,点赞发车

    前言

      说到数据库优化脱口而出就是添加索引,如果不会用请移步《解锁数据库系列》数据库索引已为你备好!如果你也和我一样一直搞不懂数据库索引底层数据结构,懵X树上懵X果,懵X树下你和我,请在下方留言告诉我不止我一个,心里好受点,可是现在我已悟透,看完整篇文章相信你也和我一样拨开迷雾对天笑说:就这?对它就这,话不多说直接发车!

    索引数据结构

      数据库索引主要有Hash表、二叉树、红黑树、B树、B+树,我们MySQL使用的是B+树!

    Hash索引

    介绍

      Hash索引(hash index)基于哈希表实现,对于每一行数据,存储引擎都会对所有的索引列计算一个hash码(hash code),哈希码是一个较小的值,哈希索引将所有的哈希码存储在索引中,同时在哈希表中保存指向每个数据行的指针。如果hash码一样则会采用链表的形式存储,类似于HashMap,Hash索引适用于精准查询。

    举例

      有下表
    在这里插入图片描述
      如果我们在name列建立索引,name数据库会使用哈希算法计算name列每一行数据的hash值并进行存储。因为Hash值是随机计算的,所以可能存在冲突,假如计算结果如下
    在这里插入图片描述
      Hash索引数据结构如下
    在这里插入图片描述

    我们有一条SELECT id,name,age FROM t_user WHERE name=‘石小添’; 这样的一条SQL可以直接对石小添 按哈希算法算出来一个Hash值,通过该值找到对应的记录指针,通过记录指针找到表中的哪一行数据,最后比较name是否为石小添,以保证就是要查找的行。
    但是如果我们有 SELECT id,name,age FROM t_user WHERE name>‘石小添’; 这样的一条SQL则无能为力,因为Hash表支持快速的精确查询,但是不支持范围查询

    Hash索引总结

    • 哈希索引只包含哈希值和行指针,而不存储字段值,所以不能使用索引中的值来避免读取行
    • 哈希索引数据并不是按照索引值顺序存储的,所以也就无法用于排序
    • 哈希索引不支持部分索引列匹配查找,因为哈希索引始终是使用索引列的全部内容来计算哈希值
    • 哈希索引只支持等值比较查询,不支持任何范围查询
    • 访问哈希索引的数据非常快,除非有很多哈希冲突(不同的索引列值却有相同的哈希值)。当出现哈希冲突的时候,存储引擎必须遍历链表中所有的行指针,逐行进行比较,直到找到所有符合条件的行
    • 如果哈希冲突很多的话,一些索引维护操作的代价也会很高。例如,如果在某个选择性很低(哈希冲突很多)的列上建立哈希索引,那么当从表中删除一行时,存储引擎需要遍历对应哈希值的链表中的每一行,找到并删除对应行的引用,冲突越多,代价越大

    二叉树

      二叉树(Binary Tree)是每个结点最多有两个子树的树结构。通常子树被称作“左子树”(left subtree)和“右子树”(right subtree)。二叉树常被用于实现二叉查找树和二叉堆。
    在这里插入图片描述

    举例

    在这里插入图片描述

    id列添加索引使用二叉树进行存储,如下图

    在这里插入图片描述

    如果我们的数据是单边增长的最终二叉树可能成为一个链表,我们查询一个数据如下图

    在这里插入图片描述

    如果有一条SQLSELECT id,name,age FROM tb_user WHERE id=7 ,对该字段创建索引并且使用的是二叉树维护它会查找6次,速度和没有创建索引是一样的!
    二叉树索引在索引字段是连续时或其他场景下性能很低,而且这棵树是不平衡的严重倾斜,我们就此引出红黑树

    二叉树特点

    • 若它的左子树不空,则左子树上所有结点的值均小于它的根节点的值;
    • 若它的右子树上所有结点的值均大于它的根节点的值;
    • 它的左、右子树也分别为二叉排序树

    红黑树

      红黑树(Red Black Tree)是一种含有红黑结点并能自平衡的二叉查找树,是一种平衡二叉树。红黑树的每个节点上都有存储表示节点的颜色,可以是红(Red)或黑(Black)

    相同的,id列添加索引使用红黑树进行存储,如下图,我们会发现会做一个调整,使这棵树相对平衡,较小的值放上级节点左边,较大的值放上级节点右边

    在这里插入图片描述

    相同的去查找一样的4和7两个数据,如下图

    在这里插入图片描述

    很显然我们使用红黑树之后相对于二叉树来说,这棵树更加平衡,搜索数据也更快,MySQL仍然不用该数据结构来维护索引数据是为什么?下边来分析一下,彻底搞定

    红黑树弊端

    • 目前表中有6条数据,所以需要将这六列存储起来使用红黑树维护,那么这棵树的高度h=4,分别为2、4、6、7四个节点,这里没有问题吧
    • 我们实际项目中数据不可能只有几条,都是百万条,千万条数据,如果红黑树要维护百万条,千万条数据,那么这可红黑树的高度h=?,很好计算,如果我们要想表中存储100W条数据,也就是有100W个红黑节点,每个节点有2个分支,将整棵树撑满2^n=1000000,n就是h深度,自己算一下吧
    • 通过上边的分析,我们发现使用红黑树维护索引数据,这棵树的深度太深,太深就~~~
    • 如果你要查找的数据在叶子节点,那么查询的次数也是蛮多的

    通过上边的红黑树我们可以发现数据越多数高度就越高,树越高查询数据需要的次数就越多,我们控制住树的高度,就可以控制查询的次数,这就是我们的B树要来完成的伟业,所以大家不妨喝杯茶,思考一下在红黑树的基础上将树的高度控制在3-5层,进而存储千万条数据,若是你,将如何?

    B树

      二叉树和红黑树都是一个节点上存储一个数据,而B数是在红黑树的基础上一个节点上存储多个数据,所谓的B-Tree,BTree,B树说的都是同一个东西,全称Balance-tree译为平衡多路查找树平衡为左边和右边分布均匀。·多路为相对于二叉树而言,二叉树就是二路查找树,查找时只有两条路,而B-tree有多条路,即父节点有多个子节点,看图说话
    在这里插入图片描述

    哦,是这张

    在这里插入图片描述

    • 上边18、25、60是一个节点,20、23是一个节点,同一个节点上存储多个数据
    • data是在该节点上存储的数据,如果是mysql中使用B树存储的就是数据的磁盘地址,就是我们要查找的那行数据在磁盘上的位置
    • 到索引中找到对应的节点,在节点中找到对应的数据,再获取磁盘地址就可以找到这行数据

    看看B树存数据,存完之后一共有四个节点,2、4存一个节点,1一个节点,3一个节点,6、7一个节点,1比2小所以1在2的左侧,3比2大比4小,所以在2右侧4的左侧,2、4就在同一个节点上存储,6、7都比4大,所以存储在一个节点上在4的右侧

    在这里插入图片描述

    在看看B树取数据,我们第一次取4根节点直接找到数据,第二次取7,找两次确定所在节点

    在这里插入图片描述

    B树特点

    • B-Tree可以显著减少定位记录时所经历的中间过程,从而加快存取速度。这个数据结构一般用于数据库的索引,综合效率较高
    • 关键字集合分布在整颗树中,任何一个关键字出现且只出现在一个结点中
    • 节点中的数据从左到右依次排序
    • 搜索有可能在非叶子结点结束,叶子结点就是出度为0的结点就是没有子结点的结点
    • B-树的搜索,从根结点开始,对结点内的关键字(有序)序列进行二分查找,如果命中则结束,否则进入查询关键字所属范围的儿子结点;重复,直到所对应的儿子指针为空,或已经是叶子结点

    B+Tree

      B+Tree是B-Tree的变种,MySQL就是使用B+Tree作为索引数据结构,上图
    在这里插入图片描述

    • 非叶子节点并不存储数据
    • 节点冗余,叶子结点包含所有的非叶子节点
    • 数据在叶子结点存储,而且叶子结点之间有箭头指向

    B+Tree存数据

    在这里插入图片描述

    B+Tree取数据

    在这里插入图片描述

    B+Tree为什么将数据存储到叶子结点进行冗余

    data和节点都需要空间存储,如果将data移除,可以存出更多节点,MySQL中使用的B+Tree每一节点可以存储最多16KB数据可以通过SHOW GLOBAL STATUS LIKE 'InnoDb_page_size';这条SQL查询,在16KB的情况下MySQL使用B+Tree可以存储更多的索引元素,若表中id使用bigint当做索引占8Byte,同时使用6Byte记录该节点子节点位置那么一个索引字段占8+6=14Byte,16KB/14Byte=1170,每一个节点可以存储1170个元素
    在这里插入图片描述

    B+Tree存满可以存储多少数据

    上边我们计算出每一个节点可以存储1170个元素,每一个节点还有子节点,假如树高为3每一个索引占1KB大小,这个1KB已经不小了,那么它可以存储1170*1170*16=2190W条数据,完全满足我们千万级别数据表的查询

    B+Tree叶子结点剪头是干嘛的

    B+树中的非叶子节点会冗余一份在叶子节点中,并且叶子节点之间用指针相连,最开始的Hash不支持范围查询,二叉树树高很高,只有B树跟B+有的一比,B树一个节点可以存储多个元素,相对于红黑树整体的树高降低了,磁盘IO效率提高了。而B+树是B树的升级版,只是把非叶子节点冗余一下,这么做的好处是为了提高范围查找的效率。提高了的原因也无非是会有指针指向下一个节点的叶子节点

    B+Tree特点

    • 所有关键字都出现在叶子节点的链表中(稠密索引),且链表中的关键字恰好有序
    • 在B-树基础上,为叶子节点增加链表指针,所有关键字都在叶子节点中出现,非叶子节点作为叶子节点的索引;
    • B+树总是到叶子节点才命中数据不可能在非叶子节点命中
    • 更适合文件索引系统
    • 单一节点存储的元素更多,使得查询的IO次数更少,所以也就使得它更适合做为数据库MySQL的底层数据结构

    到这我们介绍了Hash、二叉树、红黑树、B-Tree、B+Tree每种数据结构,并且得出结论Mysql使用B+Tree作为维护索引的数据结构,可以提高查询索引时的磁盘IO效率,并且可以提高范围查询的效率,并且B+树里的元素也是有序的,接下来我们就说说Mysql中常见的两种存储引擎具体如何使用索引

    Myisam存储引擎索引实现

    创建表最后一行ENGINE=MyISAM

    CREATE TABLE `tb_myisam` (
      `id` int(11) NOT NULL,
      `col1` varchar(255) DEFAULT NULL,
      `col2` varchar(255) DEFAULT NULL,
      PRIMARY KEY (`id`)
    ) ENGINE=MyISAM DEFAULT CHARSET=utf8;
    

    磁盘存储

    在这里插入图片描述

    一个myisam表创建之后在磁盘上会有三个文件frmMYDMYI维护
    frm:存储表结构
    MYD:存储表数据
    MYI:存储表中索引

    添加数据

    insert into tb_myisam (id,col1,col2) VALUES
    (2,"测试数据2","测试数据22"),
    (4,"测试数据4","测试数据44"),
    (5,"测试数据5","测试数据55"),
    (7,"测试数据7","测试数据77"),
    (1,"测试数据1","测试数据11"),
    (3,"测试数据3","测试数据33"),
    (6,"测试数据6","测试数据66");
    

    查看数据

    SELECT id,col1,col2 FROM tb_myisam
    

    在这里插入图片描述

    可以看到数据排序方式按照插入顺序排序

    Myisam索引维护

    在id列创建索引,左上角为数据维护在B+Tree中结构,右下角为数据表数据,B+Tree叶子结点下方的data存储的就是该行数据对应的磁盘地址,加入有一条SELECT id FROM tb_myisam WHERE id=3 会先到索引文件中找3这个节点,再取出对应磁盘地址,到MYD文件中找到这一行数据实现查询。

    在这里插入图片描述

    InnoDB存储引擎索引实现

    创建表

    CREATE TABLE `tb_innodb` (
      `id` int(11) NOT NULL,
      `col1` varchar(255) DEFAULT NULL,
      `col2` varchar(255) DEFAULT NULL,
      PRIMARY KEY (`id`)
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
    

    磁盘存储

    在这里插入图片描述

    一个InnoDB表创建之后在磁盘上会有两个文件frmibd维护
    frm:存储表结构
    ibd:存储表索引和数据

    添加数据

    insert into tb_innodb (id,col1,col2) VALUES
    (2,"测试数据2","测试数据22"),
    (4,"测试数据4","测试数据44"),
    (5,"测试数据5","测试数据55"),
    (7,"测试数据7","测试数据77"),
    (1,"测试数据1","测试数据11"),
    (3,"测试数据3","测试数据33"),
    (6,"测试数据6","测试数据66");
    

    查询数据

    在这里插入图片描述

    mysql主键自动创建索引,innodb搜索引擎按照主键排序

    InnoDB索引维护

    InnoDB存储引擎,表数据文件也就是ibd文件本身就是按照B+Tree组织的索引结构文件,叶节点包含了完整的数据记录
    在这里插入图片描述

    如果我们InnoDB没有索引怎么办,数据就无法存储了吗?

      大家应该通过一句话InnoDB表必须有主键,并且这个主键建议使用整型自动递增的,如果你表中有主键那么会在主键上添加索引来维护,如果你创建表时没有指定主键,数据库会在你的表中找到唯一数据那列去维护,如果找不到这样的列,数据库默认会自己增加一列来维护。
      推荐使用整型原因首先整型存储所占空间较小,而且比较排序时较快,可能有些公司在使用UUID当做主键等,UUID是一个随机的字符串,在比较时需要先转换再比较而且占用空间大,所以不推荐使用
      推荐自动递增是因为我们叶子结点数据从左到右依次递增排序,在做范围查询时比较方便,如果你的数值是随机的就有可能修改树原有的结构,导致分裂,裂开造成性能影响,可以看下图举例,我们最后添加8进来看变化
    在这里插入图片描述

    联合索引长什么样?

      我们在开发项目时一般不创建单列索引,而是多个键创建联合索引,现在只要你把联合索引底层原理整明白,网上看的那些MySQL索引优化原则你就可以在底层原理上去理解,而不用再去背,我是很讨厌背东西的,背完马上忘没意思,下图就是联合索引长相
    在这里插入图片描述

    假设我们联合索引为(col1,col2,col3),分别为上图绿色方格中的三行数据,分别根据col1,col2,col3三列排序,紫色为其他非索引字段,这里要明白的是联合索引是按照什么排序的,最左前缀法则为什么索引会失效,以及网上的索引优化文章为什么要求你这么写,我想经过你的思考应该都明白!一定要勤于思考!

    文章思路

    《高性能MySQL》
    《MySQL技术内幕:InnoDB存储引擎》

    本文若有任何看不懂,或者有错误的地方欢迎大家评论区留言,我时时关注哦

    我是不夜学长,用你勤劳的双手点个赞吧,这将是我创作更多优质文章的动力!

    展开全文
  • 索引原理-索引数据结构

    千次阅读 2021-01-25 22:18:20
    我们乱序插入一些数据, 我们会发现0010这个节点被“孤立”了, 随着数据量的增加树的H(高度)会随之增加, 当我们加到了N的数据量后, 我们再查询这个N. 那么这个树搜索会从根直至到N这个位置, 对于自增的表列而言, 并...

    推荐一个学习树结构的网站 --> 树结构学习网站

    本文目录:

    1. 二叉树
    2. 红黑树
    3. Hash表
    4. B树
    5. B+树
    6. 聚簇索引
    7. 非聚簇索引
    8. 联合索引

    一. 二叉树

    插入顺序: 4 2 1 10 6 7
    首先, 左侧叶子节点 < 主节点 < 右侧叶子节点
    我们乱序插入一些数据, 我们会发现0010这个节点被“孤立”了, 随着数据量的增加树的H(高度)会随之增加, 当我们加到了N的数据量后, 我们再查询这个N. 那么这个树搜索会从根直至到N这个位置, 对于自增的表列而言, 并没有明显提供查询性能. 而且有些节点甚至可能会独立存在, 拉高了树的H.
    在这里插入图片描述

    二. 红黑树

    插入顺序: 4 2 1 10 6 7
    我们会发现这棵树, 在添加的过程中, 会字段平衡节点与叶子节点之间的关系, 当一侧单向高时, 会把大于和小于的节点提上来, 左面是小于这个节点的, 右面是大于这个节点的, 它相比于二叉树, 有了一个自动平衡的功能, 但是与二叉树有一个相同的特点, 虽然数据量的增加树的高度会无限增加. 所以数据库的索引不会使用这个红黑树, 而JDK8的hashMap是数组+红黑树, 每个bucket内的红黑树节点数量也会有控制.
    在这里插入图片描述

    三. Hash表

    Hash表的索引优缺点也显而易见, 对于where条件之后的=查询, 它是可以精确到桶的位置, 然后再看桶内数据哪条数据符合条件, 拿着地址去找数据.
    但是缺点也很明显, hash冲突, 如果链表数据过多, 反而失去了索引的该有的优势, 而且它并不支持范围查询.
    在这里插入图片描述

    查看引擎的页大小, 大约为16K

    在这里插入图片描述

    四. B树

    B树, 以自增主键举例, 15,56,77,20,49就是id值, 每一个id值下面会挂着一条数据, 主节点和叶子节点是不能重复的.
    在这里插入图片描述

    五. B+树

    B+树, B树的升级版, 我们会发现相比于B树, 主节点的值是可以和叶子节点重复的, 最终会定位到最终一行上, 获取data数据. 而且data数据是一个双向链表关系. 相比于B树有什么有数呢?

    1. 主节点来看 如果主键ID是bigint类型, 那么它是8个字节, 白色的地方是指向叶子节点的地址, 在C语言中是6个字节, 那么一对就是14byte, 以页为单位, 一个页可以放16000/14=1143, 以H为3为例, 第二层的量为1143 * 1143 = 1306449, 那么第三层数据看成1KB, 那么一个页就是16条数据, H为3的话就是 1143 * 1143 * 16, 大约就是两千万的数据量, 肯定比B数结构的量多的多(B树 data以1KB算, 16000/1014=15 第二层才15*15).
    2. data双向链表就决定了B+的数据可以范围查询, 而B树有点类似与Hash表的查询了(最后一行的数据是左小右大, 但是对于范围来说查询影响不大)
      在这里插入图片描述

    六. 聚簇索引

    我们先在服务器上安装一个mysql, 创建一个test数据库,
    再创建一个 test_innodb的innoDB引擎的表
    再创建一个test_myisam的MyISAM引擎的表
    我们进入到 /var/lib/mysql路径下, 会发现以数据库命名的文件夹, 我们进到test目录下
    在这里插入图片描述
    我们发现不同引擎的数据文件是不一样的.
    innoDB引擎的文件有frm和ibd, frm是表的结构数据, ibd是索引和数据的文件
    MyISAM引擎的文件有frm和MYD以及MYI, frm仍然是表的结构数据, MYD是数据文件, MYI是索引数据文件.
    不难发现, MyISAM将索引和数据解藕存储, 但是每次查询需要两个文件联查. 在数据量以及索引足够大时MyISAM是占优的, 但是在现如今硬件足够优秀, 以及可以控制好树的高度情况下, innoDB的效率也不会比MyISAM差. 甚至更优.

    聚簇索引
    通过mysql的数据文件, 我看可以看出来InnoDB的索引和数据都在.ibd文件里, 那么数据结构也就是如下, data数据就是行数据.
    在这里插入图片描述
    name字段创建B Tree索引
    在聚簇索引存在下, 那么再创建索引字段, 他的结构就如下所示, 最终指向了ID的值.
    从这里我们可以看出来, 创建一个表带上主键是多么的重要!!!
    为什么使用自增作为主键? 如果是UUID这种, 那么树节点排序还需要计算ASCII值去比对. 相对于树结构的特性自增是很好的选择!!!

    在这里插入图片描述

    七. 非聚簇索引(MyISAM的主键索引)

    我们查看数据库的MyISAM的数据文件可以知道, 索引是MYI文件, 数据文件是MYD, 那么他的结构也就是如下所示, data指向的是数据地址.
    在这里插入图片描述

    八. 联合索引(左前缀原则)

    节点排列我们知道一定是顺序排列, 那么如果是多个字段做联合索引, 那么它的排列一定是一个字段排序, 相同时第二个对比, 第二个也相同再比对第三个字段数据的ASCII值.
    那么我们就可以知道, 如果查询where name = 'Bill’和where name = ‘Lilei’ and age = 30是可以走索引的
    如果直接where position = 'dev’是无法走索引的
    在这里插入图片描述

    展开全文
  • 索引数据结构分为哪几种 二叉树、红黑树、Hash表、B树。 在这里我们主要介绍hash表和B树 Hash表 什么是hash? hash是一种散列函数,通过将输入值映射为一个数值,如: hash(100) = 1,不同的hash算法,hash之后的值有...

    什么是索引?

    在mysql中,索引就是帮助mysql快速找到某条数据的一种数据结构,它是排好序的,独立于mysql表数据之外的。

    索引数据结构分为哪几种

    二叉树、红黑树、Hash表、B树。

    在这里我们主要介绍hash表和B树

    Hash表

    什么是hash?
    hash是一种散列函数,通过将输入值映射为一个数值,如: hash(100) = 1,不同的hash算法,hash之后的值有可能是不同的。
    Hash表是以数据映射形式存在于mysql中的,那么hash表是如何产生的呢?
    当添加一条数据到表中的时候,首先会对主键进行hash,然后将这条数据存在的地址和hash值建立一个映射关系,当我们根据主键查找这条数据的时候,只需要将主键进行hash,得到hash值,最后根据hash值就可以直接定位到这条数据。所以hash算法只需要进行一次磁盘IO,查询速度是非常快的。

    在这里插入图片描述

    BTree

    B树又称为多叉树,它在二叉树的基础之上,划分出来多个叉,我们看下它的数据结构图示。
    在这里插入图片描述

    我们从图中可以看出B树具有这几种特性:
    1.节点从左到右递增排序
    2.每个数据节点后面都会紧跟着一个指针,该指针是指向下一级的内存地址。下一级指的是位于当前指针左右两边数值中间的数据记录所存在内存中的地址。
    3.叶子节点 的指针为空
    4.所有索引元素是不重复的。
    5.每个索引节点都存着当前指向的记录数据(或内存地址)

    B+Tree

    B+树其实是B树的一个变种,它在B树的基础之上做了一些改善,将索引节点所关联的数据记录全部移到叶子节点上了,目的是为了可以存储更多的索引节点,但是却增加了索引节点的冗余,因为叶子节点包含了所有的索引节点。

    在这里插入图片描述

    从图中可以看出,B+树具有以下几个特性:
    1.叶子节点包含所有的索引节点
    2.非叶子节点不存储数据记录
    3.叶子节点之间使用指针连接,提高区间访问的便利
    4.指针所指向的索引节点的最左边都是大于等于指针所在深度左边的值

    mysql的b+ tree优化了什么?

    我们看下mysql中的B+树长什么样子的

    在这里插入图片描述

    1.增加了一个双向的指针
    2.首尾节点也通过指针进行关联起来
    主要目的是为了更加友好的支持索引内部的范围查找。如果不加双向链表指针,我们每次查找的时候,都要回到根节点查找,增加了磁盘IO,增加查询时间。

    如何计算 B+ tree最大支持数据量

    在mysql中,可以使用SHOW GLOBAL STATUS LIKE 'Innodb_page_size%'指令查找到mysql对索引节点页面大小的设置,这个参数的大小决定了我们一次性能够从磁盘盘中load出多少索引数量。
    在5.7版本中Innodb_page_size 默认设置为16384,也就是16k。
    我们现在计算下myssql中,如果存储引擎为innodb的话,大概能支撑多少量级的数据?
    我们按照高度为3的树进行计算:

    1.按照每个bigint数据类型的字段存储,每个非叶子索引节点最多需要8B
    2.再加上每个索引节点后面连接的指针,指针在innodb中设置的大小为6B
    3.两者加起来总共14B,所以一级节点总共能存储 16kB/14B = 1170个索引节点
    4.二级节点都是从一级节点划分出来,也就是一级节点中的每个节点又能划分出1170个,所以二级节点和一级节点总共能存储11701170 = 1368900个 索引节点。
    5.三级节点也就是叶子节点,叶子节点存储的是主键值+记录数据,记录数据最多为1K,这个时候主键值8B可以忽略不计了,所以每个叶子节点最多能存储16k/1k = 16条记录。
    6.所以Innodb引擎结构的表中最多能支撑1170
    1170*16 = 21902400 条数据,大概21亿,如果大于这个值,基本上都需要进行分库分表了,mysql建议B+树的深度最好小于3.
    ``

    hash算法很快,为什么mysql 很少使用hash索引?

    在上面说过,hash算法,在查找数据的时候只用进行一次磁盘IO,查询速度非常快,但是为什么mysql不推荐使用呢?主要有以下几个原因
    1.hash冲突(占比小,因为mysql的hash算法质量比较高,造成hash冲突的概率比较低)
    2.无法进行范围查询(因为hash表里面存放的是hash值,不是数据本身,所以无法进行数据的比较,如果你确定你的表中只会用到精准查找的话,则可以使用hash结构的索引)

    B tree与B+ tree区别?

    1.增加了双向链表,便于范围查找.
    2.只有叶子节点才存储数据记录,意味着可以存储更多的索引节点.

    聚集(聚簇)索引与非聚集(聚簇)索引的区别?

    聚集(聚簇)索引:索引文件与数据文件是合并在一起存放的
    非聚集(聚簇)索引:索引文件与数据文件是独立存放的

    innodb存储引擎实现(主键和辅助键)

    主键索引:
    在innodb中默认使用B+ tree结构类型,存储的是聚集索引,叶子结点的data区域存储的是当前主键关联的整条记录
    辅助键:
    辅助键的data区域存储的是主键值,也就是说如果使用辅助键索引查询,最后还得通过主键值查找对应的记录。

    myisam存储引擎的索引,不管主键还是辅建索引,data区域保存的都是所关联数据的内存地址,因为myisam是非聚集索引,索引文件和数据文件是分开存储的。

    为什么Innodb表必须有主键?并且推荐使用整型 并且 自增主键?

    1.为什么Innodb表必须有主键?
    在innodb存储引擎表中,mysql会给主键添加聚集索引,如果没有主键,mysql则会选举表中设置了唯一索引的字段设置为主键,创建主键索引;
    如果表中没有字段设置为唯一索引,则mysql会生成一个row_id,作为主键,创建主键索引。
    2.为什么mysql推荐使用整形作为主键字段类型?
    在组建B树的时候,mysql会按照从小到大的顺序进行组建,如果是整形数字的话,mysql则可以直接进行比较,如果是其它类型的话,mysql还得需要将值转换为ascill码,进行比较,会增加创建索引和查询的时间。
    3.为什么要求是自增类型?
    这是由mysql限制条件决定的:
    1.mysql设置innodb的一次性读取到内存中的页大小设置为16384B,也就是每个节点最大为16k,
    2.btree按照顺序从左往右排列;
    在这里插入图片描述

    假如现在主键不是自增的,这时候如果加入了一个新的值11,那么通过比较之后,11是需要存储在10和12之间的:
    1.如果这个时候该节点已经为16k了,再加入一个数据的话,会超过mysql设置的限制,就会出现分裂,拆分成两个节点,这个操作同样会增加索引创建的时间。
    2.如果按照字段设置为自增的,则不会插入比当前序号小的数据,只需要在右边继续扩充就行,不会出现节点分裂的情况。

    为什么非主键索引结构叶子节点存储的是主键值 (一致性和存储空间)

    1.如果存储的是具体的数据的话,会造成数据不一致的问题,因为主键索引和辅助索引会同时维护数据记录,如果有一方维护失败则会出现不一致性的问题
    2.都存储具体数据的话,会造成存储空间的浪费,如果只存储主键记录的话,可以存储更多的索引记录,但是需要二次根据主键查找具体数据,以时间换空间

    联合索引的底层存储结构

    在这里插入图片描述
    在这里插入图片描述

    微信搜一搜【乐哉开讲】关注帅气的我,回复【干货】,将会有大量面试资料和架构师必看书籍等你挑选,包括java基础、java并发、微服务、中间件等更多资料等你来取哦。

    书读的越多而不加思考,你就会觉得你知道得很多;而当你读书而思考得越多的时候,你就会越清楚地看到,你知道得很少。——伏尔泰

    展开全文
  • mysql索引数据结构

    千次阅读 2020-09-02 18:09:07
    由于 Hash 索引中存放的是经过 Hash 计算之后的 Hash 值,而且Hash值的大小关系并不一定和 Hash 运算前的键值完全一样,所以数据库无法利用索引数据来避免任何排序运算 3.Hash 索引不能利用部分索引键查询 对于...
  • Mysql索引数据结构

    万次阅读 多人点赞 2018-08-26 11:55:58
    首先,数据库索引使用树来存储,因为树的查询效率高,而且二叉查找树还可以保持数据的有序。 那么索引为什么没有使用二叉树来实现呢? 其实从算法逻辑上讲,二叉查找树的查找速度和比较次数都是最小的,但是从...
  • mysql 索引数据结构(笔记)

    千次阅读 2020-03-12 12:32:09
    索引的用途:帮助mysql高效获取数据的数据结构索引使用策略及优化: mysql优化主要分为结构优化和查询优化。 一般在数据库系统或文件系统中使用的B+Tree结构都在经典B+Tree的基础上进行了优化,增加了顺序访问...
  • 一、基础 1.什么是聚簇索引? innodb中,主键的索引结构中,既...二、mysql的innodb索引数据结构是B+树,而不是hash? 1.哈希索引适用的场景 适合等值查询(前提是不存在大量重复键值,如果存在重复键就会出现哈...
  • 它支持诸多存储引擎,各存储引擎对索引的支持也各不相同,因此MySQL支持多种索引类型,如BTree索引,B+Tree索引,哈希索引,有序数组、全文索引等等。 现实工作中如果一个sql比较慢分析一番说加一个索引吧。一般这...
  • mysql中索引数据结构简介

    千次阅读 2018-06-14 22:36:57
    mysql索引数据结构是树,常用的存储引擎innodb采用的是B+Tree。这里对B+Tree及其相关的 查找树进行简要介绍。 二、各种查找树 1、二叉排序树(也称为二叉查找树) 二叉排序树是最简单的查找树,特点: a)是一...
  • 这个问题其实还是很有趣的,我在上一篇...1、为什么数据库索引不能用二叉排序树; 2、为什么数据库索引不能用红黑树; 本篇文章增加了: 1、为什么不能使用哈希表; 2、为什么不能使用B-树; 3、为什么能使用B+树。
  • Tidb索引数据结构(LSM-TREE)

    千次阅读 2019-03-28 11:39:00
    且 merge 操作为异步操作,索引数据更新会存在一定的延迟,可能存在无效索引。由于逐层扫描和异步 merge,使得查询效率较低。 优化方式:尽可能缩小过滤范围,比如结合异步 job 获取记录频率,在保证不遗漏数据的...
  • 二维空间点索引数据结构

    千次阅读 2012-03-06 00:54:11
     KD-Tree是一种由二叉搜索树推广而来的用于多维检索的树的结构形式(K即为空间的维数)。它与 二叉搜索树 不同的是它的每个结点表示k维空间的一个点,并且每一层都根据该层的分辨器(discriminator)对相应对象做出...
  • 一个好的索引数据结构应该最大程度减少磁盘IO。 —数据库设计者巧妙地将【树节点】用【单位页】进行对应存储,这样一个节点的载入只需要一次磁盘IO。在B-Tree定义中,检索一次最多需要访问h(树高度)个节点,...
  • 最近一直在研究sphinx的工作机制,在[搜索引擎]Sphinx的介绍和原理探索简单地介绍了其工作原理之后,还有很多问题没有弄懂,比如底层的数据结构和算法,于是更进一步地从数据结构层面了解其工作原理。在网上搜了很...
  • 当我们可以最大限度地复用文件存储区时,我们就可以针对原有的数据结构进行调整,比如:可以把索引文件和数据文件合并到一个文件中而不必考虑图片的增长而导致的索引存储区空间不足的情况,可以在增加和删除数据单元...
  • 最初的金字塔模型是分为两个文件进行存储,一个是索引文件...层级索引存储了自身索引值以及图片单元索引索引文件中所存储的位置, 数据单元索引存储了每个数据单元的索引值以及每一个数据单元在数据文件中的索引位置
  • LSM-tree 一种高效的索引数据结构

    千次阅读 2012-11-13 14:11:48
    ) 描述了这种数据结构的目标和算法细节。   LSM-tree主要目标是快速地建立索引。B-tree是建立索引的通用技术,但是,在大并发插入数据的情况下,B-tree需要大量的磁盘随机IO,很显然,大量的磁盘随机IO...
  • 从GoogleMap的金字塔模型到无限级索引数据结构(一)

    千次阅读 热门讨论 2010-10-19 09:12:00
    但是往往在做GIS项目的时候会遇到一个问题:有时候客户的机器并没有连接到互联网,或者有各种各样的问题,导致通过URL的方式访问地图速度会很慢,更有一个大的问题,有的地图供应商虽然开放免费的地图数据,但对访问...
  • 数据库索引及其数据结构

    千次阅读 2018-04-08 20:26:04
    数据库索引,是数据库管理系统中一个排序的数据结构,以协助快速查询、更新数据库表中数据。索引的实现通常使用B树及其变种B+树。在数据之外,数据库系统还维护着满足特定查找算法的数据结构,这些数据结构以某种...
  • MySQL索引的本质,MySQL索引的实现,MySQL索引数据结构
  • 文件系统索引数据结构——B-/+Tree

    千次阅读 2019-06-05 00:37:16
    建立索引数据结构可以有效加快这个查找过程。目前的文件系统及数据库系统普遍采用B-/+Tree作为索引结构。对于索引查找行为本身来说,如果全部数据都加载进了速度很快的内存,使用传统的二叉树作为索引也未尝不可。但...
  • MySQL索引详解之索引数据结构

    千次阅读 2020-04-21 18:53:22
    前言 很多人对数据库索引可能都是知其然却不知其所以然,对索引没有很深入的理解,在使用过程中也一知半解,导致没有办法准确高效地使用索引,...数据库索引指的是数据库管理系统中一个排序的数据结构,以协助快速查...
  • 索引数据结构

    千次阅读 2018-09-08 08:05:03
    传统文件读取和索引方式读取文件  Select * from student where id=?... 索引是帮助高效获取数据的数据结构  索引也可能是一个文件 其他类型  1、hash Map  2、二叉树  3、红黑树  为什么选取B+树,...
  • 数据结构:八大数据结构分类

    万次阅读 多人点赞 2018-09-05 18:23:28
    数据结构分类 数据结构是指相互之间存在着一种或多种关系的数据元素的集合和该集合中数据元素之间的关系组成 。 常用的数据结构有:数组,栈,链表,队列,树,图,堆,散列表等,如图所示: 每一种数据结构都...
  • MySQL联合索引底层数据结构

    千次阅读 2020-06-09 00:55:00
    了解MySQL索引结构的基本都知道索引BTree类型是用B+树的数据结构,单列索引的结构我们很容易理解,二级索引的每个叶子节点只存储主键关键字外的一个数据,查询起来也很容易在非叶子节点进行大小值判断,最终找到叶子...
  • 深入理解MySQL索引底层数据结构与算法

    万次阅读 多人点赞 2018-10-10 11:10:58
    目录 一 理解索引的特性 二 索引的各种存储结构及其优缺点 ...索引是帮助MySQL高效获取数据的排好序的数据结构 索引存储在文件里 二 索引的各种存储结构及其优缺点 在开始讲这一小节之前,我们先来看一...
  • MySQL - 剖析MySQL索引底层数据结构

    千次阅读 2020-07-18 16:51:14
    文章目录Pre Pre 什么是索引? 通俗的说就是为了提高效率专门设计的一种 排好序的数据结构。 怎么理解呢? 举个例子哈 如上数据 ,假设有个SQL select * from t where col2 = 22 ;
  • Mysql索引底层数据结构与算法

    千次阅读 2018-10-10 17:25:44
    2,索引底层数据结构与算法 3,索引最左前缀原理   索引到底是什么 •索引是帮助MySQL高效获取数据的排好序的数据结构 索引的本质 MySQL官方对索引的定义为:索引(Index)是帮助MySQL高效获取数据的数据结构...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 798,709
精华内容 319,483
关键字:

索引的数据结构

数据结构 订阅