问题1. 数据库为什么要设计索引?

图书馆存了1000W本图书,要从中找到《架构师之路》,一本本查,要查到什么时候去?

于是,图书管理员设计了一套规则:

(1)一楼放历史类,二楼放文学类,三楼放IT类…

(2)IT类,又分软件类,硬件类…

(3)软件类,又按照书名音序排序…

以便快速找到一本书。

与之类比,数据库存储了1000W条数据,要从中找到name=”shenjian”的记录,一条条查,要查到什么时候去?

于是,要有索引,用于提升数据库的查找速度。

问题2. 哈希(hash)比树(tree)更快,索引结构为什么要设计成树型?

加速查找速度的数据结构,常见的有两类:

(1)哈希,例如HashMap,查询/插入/修改/删除的平均时间复杂度都是O(1);

(2),例如平衡二叉搜索树,查询/插入/修改/删除的平均时间复杂度都是O(lg(n));

可以看到,不管是读请求,还是写请求,哈希类型的索引,都要比树型的索引更快一些,那为什么,索引结构要设计成树型呢?

画外音:80%的同学,面试都答不出来。

索引设计成树形,和SQL的需求相关。

对于这样一个单行查询的SQL需求:

select * from t where name=”shenjian”;

确实是哈希索引更快,因为每次都只查询一条记录。

画外音:所以,如果业务需求都是单行访问,例如passport,确实可以使用哈希索引。

但是对于排序查询的SQL需求:

  • 分组:group by

  • 排序:order by

  • 比较:<、>

哈希型的索引,时间复杂度会退化为O(n),而树型的“有序”特性,依然能够保持O(log(n)) 的高效率。

任何脱离需求的设计都是耍流氓。

多说一句,InnoDB并不支持哈希索引。

问题3. 数据库索引为什么使用B+树?

为了保持知识体系的完整性,简单介绍下几种树。

第一种:二叉搜索树

二叉搜索树,如上图,是最为大家所熟知的一种数据结构,就不展开介绍了,它为什么不适合用作数据库索引?

(1)当数据量大的时候,树的高度会比较高,数据量大的时候,查询会比较慢;

(2)每个节点只存储一个记录,可能导致一次查询有很多次磁盘IO;

画外音:这个树经常出现在大学课本里,所以最为大家所熟知。

第二种:B树

B树,如上图,它的特点是:

(1)不再是二叉搜索,而是m叉搜索;

(2)叶子节点,非叶子节点,都存储数据;

(3)中序遍历,可以获得所有节点;

画外音,实在不想介绍这个特性:非根节点包含的关键字个数j满足,(┌m/2┐)-1 <= j <= m-1,节点分裂时要满足这个条件。

B树被作为实现索引的数据结构被创造出来,是因为它能够完美的利用“局部性原理”。

什么是局部性原理?

局部性原理的逻辑是这样的:

(1)内存读写块,磁盘读写慢,而且慢很多;

(2)磁盘预读:磁盘读写并不是按需读取,而是按页预读,一次会读一页的数据,每次加载更多的数据,如果未来要读取的数据就在这一页中,可以避免未来的磁盘IO,提高效率;

画外音:通常,一页数据是4K。

(3)局部性原理:软件设计要尽量遵循“数据读取集中”与“使用到一个数据,大概率会使用其附近的数据”,这样磁盘预读能充分提高磁盘IO;

B树为何适合做索引?

(1)由于是m分叉的,高度能够大大降低;

(2)每个节点可以存储j个记录,如果将节点大小设置为页大小,例如4K,能够充分的利用预读的特性,极大减少磁盘IO;

第三种:B+树

B+树,如上图,仍是m叉搜索树,在B树的基础上,做了一些改进

(1)非叶子节点不再存储数据,数据只存储在同一层的叶子节点上;

画外音:B+树中根到每一个节点的路径长度一样,而B树不是这样。

(2)叶子之间,增加了链表,获取所有节点,不再需要中序遍历;

这些改进让B+树比B树有更优的特性:

(1)范围查找,定位min与max之后,中间叶子节点,就是结果集,不用中序回溯;

画外音:范围查询在SQL中用得很多,这是B+树比B树最大的优势。

(2)叶子节点存储实际记录行,记录行相对比较紧密的存储,适合大数据量磁盘存储;非叶子节点存储记录的PK,用于查询加速,适合内存存储;

(3)非叶子节点,不存储实际记录,而只存储记录的KEY的话,那么在相同内存的情况下,B+树能够存储更多索引;

最后,量化说下,为什么m叉的B+树比二叉搜索树的高度大大大大降低?

大概计算一下:

(1)局部性原理,将一个节点的大小设为一页,一页4K,假设一个KEY有8字节,一个节点可以存储500个KEY,即j=500

(2)m叉树,大概m/2<= j <=m,即可以差不多是1000叉树

(3)那么:

一层树:1个节点,1*500个KEY,大小4K

二层树:1000个节点,1000*500=50W个KEY,大小1000*4K=4M

三层树:1000*1000个节点,1000*1000*500=5亿个KEY,大小1000*1000*4K=4G

画外音:额,帮忙看下有没有算错。

可以看到,存储大量的数据(5亿),并不需要太高树的深度(高度3),索引也不是太占内存(4G)。

总结

  • 数据库索引用于加速查询

  • 虽然哈希索引是O(1),树索引是O(log(n)),但SQL有很多“有序”需求,故数据库使用树型索引

  • InnoDB不支持哈希索引

  • 数据预读的思路是:磁盘读写并不是按需读取,而是按页预读,一次会读一页的数据,每次加载更多的数据,以便未来减少磁盘IO

  • 局部性原理:软件设计要尽量遵循“数据读取集中”与“使用到一个数据,大概率会使用其附近的数据”,这样磁盘预读能充分提高磁盘IO

  • 数据库的索引最常用B+树:

(1)很适合磁盘存储,能够充分利用局部性原理,磁盘预读;

(2)很低的树高度,能够存储大量数据;

(3)索引本身占用的内存很小;

(4)能够很好的支持单点查询,范围查询,有序性查询;

数据库索引,到底是什么做的?-- 转自沈剑公众号相关推荐

  1. 用新华字典来彻底解释清:数据库索引到底是什么

    点击上方蓝字设为星标 下面开始今天的学习- 作者:兜里有辣条 来源:segmentfault.com/a/1190000018153249  说在前面  数据库超级重要,这个大家应该清楚,学过数据库的 ...

  2. 数据库怎么用Java做封面_一个毫无用处的公众号封面生成器

    一个毫无用处的公众号封面生成器 对于一个没有任何艺术细胞的人,写公众号最头疼的无异于文章封面了. 要么选不好图,选好图了呢,公众号这个2.35:1的诡异比例还会涉及到裁剪的问题... 所以或许你已经发 ...

  3. 如何做一个能赚钱的技术公众号?

    晓衡上周去了趟苏州,有幸参考技术圈公众号主的聚会.回来后,有朋友问我有些什么收获,这此收获最大在于了解到了关于技术公众号是如何赚钱的逻辑.而且我也发现社区有越来越多的发者,开始尝试在公众号上发自己的技 ...

  4. PHP怎么做微信助力,微信助力活动怎么做?教你如何在公众号制作微信助力活动...

    微信助力活动是什么?简单的来说是一个依靠分享粉丝给自己助力,也叫微助力或分享助力,助力活动以后有个排行榜,商家可以根据排名,给予一定的物质奖励,可以吸引来大量的新人关注公众号,下面具体介绍微信公众号助 ...

  5. 分享公众号预约怎么做_教你实现微信公众号预约制作步骤的方法

    在日常生活中,我们身边有着各种各样的微信公众号预约系统,例如门诊挂号预约或者各种报名预约,通过在线的报名预约系统,用户不用在跑去现场进行预约,这样极大的方便了用户,同时也方便商家统一管理用户的预约订单 ...

  6. 怎样做一个网课查题公众号

    成品效果图如下 方便又简单的教程 步骤一:进入微信公平台官网(https://mp.weixin.qq.com)按照指引注册. 详细教程 第一步点击右上角立即注册 如已注册微信公众号扫码即可登录 步骤 ...

  7. 数据库索引如何工作?原理

    原文地址:https://blog.csdn.net/weiliangliang111/article/details/51333169 数据库索引到底是什么,是怎样工作的? 我们通过一个简单的例子来 ...

  8. 白杨SEO:做个世界杯公众号怎么样?以2022年卡塔尔世界杯来做微信搜一搜的SEO流量实战举例

    做个世界杯公众号怎么样? 如上图,图片在公众号白杨SEO上去看.同样是世界杯,同样是站长,有人只关注到世界杯本身,有人开始关注思考到搞世界杯流量,尤其微信上公众号流量,不再局限于网站流量. 但是,即使 ...

  9. 白杨SEO:公众号、小程序微信服务搜索怎么做?搜一搜服务搜索排名规则解析

    新知达人, 白杨SEO:公众号.小程序怎么做微信服务搜索? 大纲如下: 1.搜一搜功能有哪些?品牌官方区怎么申请和条件? 2.微信搜一搜的服务搜索是什么? 3.微信公众号怎么做服务搜索? 4.微信小程 ...

最新文章

  1. SpringBoot 2.x 使用 JWT(JSON Web Token)
  2. 遇见BUG(1):都是非时钟专用引脚惹的祸?
  3. 【深度学习笔记】Precision、Recall
  4. WINCE开机显示logo之前先显示白屏的问题
  5. Spring Boot 整合 Redis 实现缓存操作
  6. mybatis collection_MyBatis之关联查询
  7. Mapreduce的分区—Partitioner
  8. Java修饰符public,private,protected及默认的区别
  9. 2020定额水平测算——“15定额工程”一键转换“20定额工程”
  10. 大学计算机试题深圳大学,深圳大学期末考试试卷参考答案.doc
  11. SPOJ COT 10628 Count on a tree
  12. SAR影像辐射定标工程化实现之COSMO-Skymod
  13. LVDS 显示屏的两种接口标准:VESA 和 JEIDA;单/双路 LVDS 信号
  14. 都没滤网质量重要 细数净化器鸡肋功能
  15. 计算机网络实验(华为eNSP模拟器)——第十一章 帧中继网络
  16. Unity 之 音频类型和编码格式介绍
  17. 线性探测法和平方探测法 - 哈希表 - 完整代码
  18. Android 读取系统联系人
  19. 下载与安装nexus3
  20. 计算机视觉方向就业怎么样?可以做什么?

热门文章

  1. 阿里安全潘多拉实验室首先完美越狱苹果iOS 11.2
  2. android 获取图片的真实地址
  3. 自签发SSL证书签发生成过程
  4. 全国增值税发票查验平台 | 免验证码
  5. SQL如何合并两个表
  6. 基于爬虫+人脸识别库实现指定人物自动采集
  7. JPA设置in参数时报错(Encountered array-valued parameter binding, but was expecting [java.lang.String (n/a)])
  8. 可视化Docker管理工具-DockerUI
  9. java实现模拟鼠标键盘操作
  10. swagger 源代码_我们如何使用swagger代码生成器从Angular 4更新到Angular 5