热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

数据库索引原理(深入浅出的学习)

数据库索引原理(深入浅出的学习),Go语言社区,Golang程序员人脉社

最近学习到数据库的索引,发现索引的底层原理还 “大有文章”。

通过网上的搜索来的一些学习资料,进行记录与学习

(浅)最直观的观察:https://www.cnblogs.com/aspwebchh/p/6652855.html (转)

(深)深层次的学习:https://blog.csdn.net/waeceo/article/details/78702584 (转)

(浅)使用的方式:https://blog.csdn.net/tongdanping/article/details/79878302 (转)

学习总结

通过以上几篇别人的学习经验,经过自己的消化和总结出一些自己的东西。作为自己的学习笔记。

以下将会从MySQL中的MyISAM 和InnoDB两种存储引擎讨论它们的区别,以及两种不同的存储引擎的底层索引原理

一、MyISAM 和InnoDB存储引擎的区别

MyISAM

MyISAM的存储文件分为 结构(***.frm)、数据(***.MYD)、索引(***.MYI) 三个存储文件

不支持事务和外键,对表的操作是以表级锁。只要是在具体操作表时,都是锁住整张表,所以并发性较InnoDB稍低。

但同时MyISAM又是Indexed Sequential Access Method (有索引的顺序访问方法) ,所以在执行一些简单的select操作的时候,速度会较InnoDB稍快。

总结:大量的单一查询操作、不常对表数据进行更新和写入。可优先考虑MyISAM存储引擎

InnoDB

InnoDB的存储文件分为:结构(***.frm)、数据索引文件(***.ibd) 两个存储文件

同MyISAM存储引擎不同的是,InnoDB是把索引文件和数据文件归并为同一文件。这是由于InnoDB的底层索引的原因(下文会讨论到)

InnoDB是支持事务、外键以及行级锁的。 因为具有行级锁的特性,所以相同情况下操作数据库,InnoDB的并发性会稍高于MyISAM,更加适合高并发下的大量的写入操作。

总结:InnoDB支持事务、外键以及行级锁,适合需要大量的写入操作。并发性较MyISAM稍高

二、MyISAM 和InnoDB 底层索引原理

说到索引,目前大多数主流索引的方式都为:BTree 、 B+-Tree 、 哈希索引 、全文索引 等等

今天主要讨论的MyISAM 和 InnoDB 索引的数据结构都是B+Tree,而哈希索引主要是用于内存存储引擎(Memory)。其他的索引的数据结构本次不过多讨论。

并且,需要了解为什么要使用B+Tree作为索引,而不用红黑树等其他数据结构还需要了解主存读取原理磁盘读取原理等相关知识。由于上文学习链接中已经讲解的很好了,这里不做过多阐释。想了解的同学可以直接查看第二个学习链接(深)

这里以个人理解的角度做一个简单快速的总结概括

主存(RAM)读取是快速的,不会因为“距离” (物理地址的间距)产生时间损耗。 主存读取的速度主要是受读取次数的影响,所以这并不是选择B+Tree作为索引的主要条件。

而磁盘(ROM)读取是需要寻道时间(改变磁头、转动磁盘等),会存在“距离”的影响。并且,一般情况下索引文件都是放在磁盘上,所以更多的是和磁盘打交道。所以数据库系统的设计者就很巧妙的将B+Tree的每一个节点设计为一个页的大小(4k左右)这样再根据计算机中著名的局部性原理,就可以减少因为缺页中断引起的寻道时间增加的问题(这部分主要是操作系统课程知识)

MyISAM 索引原理

在上文中说到,MyISAM存储引擎的表是有三个文件的。其中数据文件和索引文件是分开的。 索引文件中的索引是以B+Tree数的形式存储。

树中有(key,data)字段,非叶子节点的data存放的是指向下一层节点的指针,叶子节点的data域存放的是真实记录的物理地址指针(记录在磁盘中的物理地址)。而key存放的是索引字段的值。

MyISAM的主键索引非聚集索引,它的所有辅助索引也是非聚集索引。*它们所有的叶子节点的data域存放的都是数据的物理地址

主键索引

辅助索引
(图来源都为上文的学习链接中)

InnoDB索引原理

而InnoDB是索引文件和数据文件归并在一起。因为InnoDB是在表创建的同时,就会通过主键创建B+Tree的聚集索引结构。 每个叶子节点里存放的并不是数据的物理地址,而是真实数据记录

所以InnoDB通过主键索引的速度会很快

但同时,索引和数据归并在一起的文件所占据的存储空间也更为的庞大。在对表进行写操作的同时,也要耗费更多的资源去维护索引文件(B+Tree的结构)

InnoDB的辅助索引同MyISAM的辅助索引一样,都是非聚集索引。 但是InnoDB的辅助索引中,叶子节点的data域存放的并不是数据的物理地址,而是存放当前索引所对应的记录主键的值

InnoDB的辅助索引查找过程分为两步:

  1. 通过辅助索引找到主键的值
  2. 再根据主键的聚集索引找到真实的数据记录

这是在索引都是单列存在的情况(只有一个字段作为辅助索引),当出现联合索引的时候,非聚集索引就会变为覆盖索引。在下文中将会和进行讨论。

需额外注意:在使用InnoDB存储引擎的时候,在可能的情况下,尽量选择一个与 业务无关,自动增长的字段作为主键(通常情况下的id)。避免选择如:学号、身份证号这种字段作为主键。

这是由于InnoDB的索引结构B+Tree在表创建时,会自动根据主键创建一颗索引树。(如果没有显示的给出主键,MySQL的内部机制会自己制定一个主键)

这颗B+Tree的Key就是主键的值,这就要求主键的长度尽量短,这样在索引的时候速度才能更快。

而由于B+Tree的特性,如果选择一个自动增长的主键,那么在添加的新记录的时候,就只要需要在最底层的叶子节点排列的最末尾增加节点,不需要任何移动节点(有点类似于单链表,在链表的尾部增加节点效率是最高的。而如果在中间插入一个新的节点,就需要移动节点,效率较差。 当然,这里的B+Tree可能还需要重新排序,逻辑更为复杂。)

原理图:(图来源都为上文的学习链接中)
在这里插入图片描述

在这里插入图片描述

覆盖索引原理

上面的MyISAM是非聚集索引,而InnoDB是聚集索引。区别在于一个存储的是数据的物理地址,一个存储的是真实的数据。 而覆盖索引是在复合索引(多个字段联合构成的索引)中出现。

覆盖索引的原理是,你想查找一个字段的信息,索引中key的值就是你所需要的信息。那么就不必在通过data域中的物理地址或主键进行二次索引遍历另一颗索引树了。

原理图如下:(图来源都为上文的学习链接中)

这是非覆盖索引的情况:
在这里插入图片描述

这是覆盖索引的情况:
在这里插入图片描述

而联合索引中又包含最左前缀原理

最左前缀原理

最左前缀是在联合索引的时候出现的。当多个字段构成联合索引时,如:。如果查询条件为 where col1 = 20;则可以使用该联合索引。 如果为 where col2 = 20 则不能使用该联合索引

这与MySQL中的内部机制有关,如果要使用联合所用,必须是从联合索引字段的最左侧的第一个字段,这也是构建联合索引需要注意的(字段的选取,应按字段使用的频率从高到底排序)

还有一小技巧,如用到col1 和 col3的联合条件查询时,这是不能使用联合索引的。因为中间出现了一个“坑”(缺少col2)。那么在col2字段值的选择性较少的情况下,可通过把col2的所有字段可能取值通过 IN 包含进来。但是在字段值的选择性很多情况下,这种情况就不适用。可能就需要重新构建一个的联合索引。

三、索引适合场景

1. 表中记录数很多的情况下 (一般以2000为分界线,2000以下不必构建索引,因为遍历整张表的速度并不会比索引慢多少)

2.字段的选择性较大的情况下(如果一个字段的选择性很低的情况下,如:性别,就不必建立索引了,因为即使构建了索引,效率一样不是很高,这是由于B+Tree的原理。 而如果索引的选择性很大,如:真实姓名 那么使用索引的查询效率就很有很大的提升)

以上就是MyISAM 和 InnoDB 存储引擎的区别(包括索引原理的区别)的学习总结了,还需要额外涉及到:数据结构、操作系统等课程的知识。

接下来有时间,会重新详细的记录一下B+Tree 等等 数据结构的知识

还处于学习阶段,如果有错误,希望大家可以指正


推荐阅读
  • Go GUIlxn/walk 学习3.菜单栏和工具栏的具体实现
    本文介绍了使用Go语言的GUI库lxn/walk实现菜单栏和工具栏的具体方法,包括消息窗口的产生、文件放置动作响应和提示框的应用。部分代码来自上一篇博客和lxn/walk官方示例。文章提供了学习GUI开发的实际案例和代码示例。 ... [详细]
  • MySQL中的MVVC多版本并发控制机制的应用及实现
    本文介绍了MySQL中MVCC的应用及实现机制。MVCC是一种提高并发性能的技术,通过对事务内读取的内存进行处理,避免写操作堵塞读操作的并发问题。与其他数据库系统的MVCC实现机制不尽相同,MySQL的MVCC是在undolog中实现的。通过undolog可以找回数据的历史版本,提供给用户读取或在回滚时覆盖数据页上的数据。MySQL的大多数事务型存储引擎都实现了MVCC,但各自的实现机制有所不同。 ... [详细]
  • 一、Hadoop来历Hadoop的思想来源于Google在做搜索引擎的时候出现一个很大的问题就是这么多网页我如何才能以最快的速度来搜索到,由于这个问题Google发明 ... [详细]
  • 安装mysqlclient失败解决办法
    本文介绍了在MAC系统中,使用django使用mysql数据库报错的解决办法。通过源码安装mysqlclient或将mysql_config添加到系统环境变量中,可以解决安装mysqlclient失败的问题。同时,还介绍了查看mysql安装路径和使配置文件生效的方法。 ... [详细]
  • 本文介绍了数据库的存储结构及其重要性,强调了关系数据库范例中将逻辑存储与物理存储分开的必要性。通过逻辑结构和物理结构的分离,可以实现对物理存储的重新组织和数据库的迁移,而应用程序不会察觉到任何更改。文章还展示了Oracle数据库的逻辑结构和物理结构,并介绍了表空间的概念和作用。 ... [详细]
  • 本文介绍了如何使用php限制数据库插入的条数并显示每次插入数据库之间的数据数目,以及避免重复提交的方法。同时还介绍了如何限制某一个数据库用户的并发连接数,以及设置数据库的连接数和连接超时时间的方法。最后提供了一些关于浏览器在线用户数和数据库连接数量比例的参考值。 ... [详细]
  • eclipse学习(第三章:ssh中的Hibernate)——11.Hibernate的缓存(2级缓存,get和load)
    本文介绍了eclipse学习中的第三章内容,主要讲解了ssh中的Hibernate的缓存,包括2级缓存和get方法、load方法的区别。文章还涉及了项目实践和相关知识点的讲解。 ... [详细]
  • sklearn数据集库中的常用数据集类型介绍
    本文介绍了sklearn数据集库中常用的数据集类型,包括玩具数据集和样本生成器。其中详细介绍了波士顿房价数据集,包含了波士顿506处房屋的13种不同特征以及房屋价格,适用于回归任务。 ... [详细]
  • svnWebUI:一款现代化的svn服务端管理软件
    svnWebUI是一款图形化管理服务端Subversion的配置工具,适用于非程序员使用。它解决了svn用户和权限配置繁琐且不便的问题,提供了现代化的web界面,让svn服务端管理变得轻松。演示地址:http://svn.nginxwebui.cn:6060。 ... [详细]
  • 如何去除Win7快捷方式的箭头
    本文介绍了如何去除Win7快捷方式的箭头的方法,通过生成一个透明的ico图标并将其命名为Empty.ico,将图标复制到windows目录下,并导入注册表,即可去除箭头。这样做可以改善默认快捷方式的外观,提升桌面整洁度。 ... [详细]
  • 原文地址:https:www.cnblogs.combaoyipSpringBoot_YML.html1.在springboot中,有两种配置文件,一种 ... [详细]
  • 本文详细介绍了MysqlDump和mysqldump进行全库备份的相关知识,包括备份命令的使用方法、my.cnf配置文件的设置、binlog日志的位置指定、增量恢复的方式以及适用于innodb引擎和myisam引擎的备份方法。对于需要进行数据库备份的用户来说,本文提供了一些有价值的参考内容。 ... [详细]
  • 本文介绍了Hyperledger Fabric外部链码构建与运行的相关知识,包括在Hyperledger Fabric 2.0版本之前链码构建和运行的困难性,外部构建模式的实现原理以及外部构建和运行API的使用方法。通过本文的介绍,读者可以了解到如何利用外部构建和运行的方式来实现链码的构建和运行,并且不再受限于特定的语言和部署环境。 ... [详细]
  • 数据库(外键及其约束理解)(https:www.cnblogs.comchenxiaoheip6909318.html)My ... [详细]
  • Google Play推出全新的应用内评价API,帮助开发者获取更多优质用户反馈。用户每天在Google Play上发表数百万条评论,这有助于开发者了解用户喜好和改进需求。开发者可以选择在适当的时间请求用户撰写评论,以获得全面而有用的反馈。全新应用内评价功能让用户无需返回应用详情页面即可发表评论,提升用户体验。 ... [详细]
author-avatar
ala
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有