| |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
-> 数据结构与算法 -> 索引的数据结构 -> 正文阅读 |
|
[数据结构与算法]索引的数据结构 |
索引常见的有三种数据结构:哈希表,有序数组和二叉树。 MySQL使用了B+树。 下面分别介绍下三种数据结构1、哈希表(散列表)
hash算法原理:hash计算后的数据都会进入到容器Hash桶内,桶内按照下标位置分配好了内存空间,如果通过hash()计算后得到的值为2,将该数据放到次下标对应的区域。如下图 仅通过一次hash计算就可以确定数据的存储位置,如查询李四: ① 通过hash(李四)=2 ②把hash桶内的下标为2的数据load到内存,进行比较 hash仅使用了一次I/O就能拿到数据,B+Tree可能会有多次,所以一些场景hash索引会比B+Tree更高效。但是这种结构对范围查询不友好,所以MySQL底层基本用的是B+Tree。 2、有序数组有序数组在范围查找中可以使用二分法,能大大缩短查询时间,时间复杂度是O(log(N))。如果在中间插入数据时,需要移动后续数组,成本很高,所以有序数组索引只适用于静态存储引擎。 3、二叉树二叉树:右侧元素大于父元素数据,左侧数据小于父元素数据 红黑树(平衡二叉树):与二叉树结构一样,但是在生成的过程中红黑树会自动平衡节点 b-Tree:
当索引结构以B-Tree数据结构创建时,查找Clo2 = 66 的数据: 1.将树的第一层所有数据load到内存,使用比对算法(如:二分查找)进行比对 a.如果有66则将对应的data数据从内存中读取出来 b.如果没有,则会找66对应的区间地址(35-80) 2.将35-80这一页的所有数据再拿出来与66做比较 a.如果有66则将对应的data数据从内存中读取出来 b.如果没有,则会找66对应的区间地址 以此类推,直到找到66或者这一系列的数据比对完毕。 使用了B-Tree数据结构后,我们查询Clo2=66的数据只做了两次的I/O,比红黑树的效率更高一些。 b+Tree:
面试相关问题:问题1:为什么非叶子节点不存储data,可以放更多的索引?通过 SHOW GLOBAL STATUS like 'Innodb_page_size';可以看到Mysql数据库中定义文件页大小是16384B(16KB)。 如果叶子节点不存储data,假设字段类型是BigInt,字段值占用8B,地址值占用6B,一层16KB大概可以存储1170个索引值。 如果叶子节点存储data,一般的data+字段值+地址值不会大于1KB,我们就按照平均1KB计算,一层16KB也就只能存储16个索引值 问题2:为什么MYSQL叶文件默认是16KB?由问题1知道第一层一页数据可以存1170个索引值,如果再加一层,第一层的每一个地址值指向第二层的一页数据,我们就可以存储 1170X1170 个索引值,第二层每个地址值指向第三层的一页数据,第三层的叶子节点要带数据存储每一页只存16个数据,三层高的树可以存储 1170 X 1170 X 16 大约2千万左右的数据。 问题3:叶子节点指针的作用?B+Tree有链接指针可以快速的找下一页的数据,B-Tree没有指针,当取完当前区域的数据后,还得回到根节点(第一层)查找大于28的数据再做对应的I/O。 所以B+Tree可以通过叶子节点指针提高区间访问的性能。 问题4:MySQL中存储索引用到的数据结构是B+树,B+树的查询时间跟树的高度有关,是log(n),如果用hash存储,那么查询时间是O(1)。既然hash比B+树更快,为什么mysql用B+树来存储索引呢?1、从内存角度上说,数据库中的索引一般时在磁盘上,数据量大的情况可能无法一次性装入内存,B+树的设计可以允许数据分批加载。 2、从业务场景上说,如果只选择一个数据那确实是hash更快,但是数据库中经常会选中多条这时候由于B+树索引有序,并且又有链表相连,它的查询效率比hash就快很多了。 问题5:数据库索引为什么要用B+树而不是B-树和红黑树呢?
问题6:B树相对于红黑树的区别在大规模数据存储的时候,红黑树往往出现由于树的深度过大而造成磁盘IO读写过于频繁,进而导致效率低下的情况。为什么会出现这样的情况,我们知道要获取磁盘上数据,必须先通过磁盘移动臂移动到数据所在的柱面,然后找到指定盘面,接着旋转盘面找到数据所在的磁道,最后对数据进行读写。磁盘IO代价主要花费在查找所需的柱面上,树的深度过大会造成磁盘IO频繁读写。根据磁盘查找存取的次数往往由树的高度所决定,所以,只要我们通过某种较好的树结构减少树的结构尽量减少树的高度,B树可以有多个子女,从几十到上千,可以降低树的高度。 |
|
|
上一篇文章 下一篇文章 查看所有文章 |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 | -2024/11/25 20:31:23- |
|
网站联系: qq:121756557 email:121756557@qq.com IT数码 |