MySQL学习Day19——索引的数据结构

news2024/10/6 12:34:33

一、为什么使用索引:

索引是存储引擎用于快速找到数据记录的一种数据结构,就好比一本教课书的目录部分,通过目录中找到对应文章的页码,便可快速定位到需要的文章。MySQL中也是一样的道理,进行数据査找时,首先查看查询条件是否命中某条索引,符合则通过索引査找相关数据,如果不符合则需要全表扫描,即需要一条一条地查找记录,直到找到与条件符合的记录。

二、索引及其优缺点:

1.索引概述:索引是帮助MySQL高效获取数据的数据结构。索引是数据结构,可以简单地理解为排好序的快速查找数据结构。满足特定查找算法,这些数据结构以某种方式指向数据,这样就可以在这些数据结构的基础上实现高级查找算法。索引是在存储引擎中实现的,因此每种存储引擎的索引不一定完全相同,并且每种存储引擎不一定支持所有索引类型。同时存储引擎可以定义每个表的最大索引数和最大索引长度。

2.使用索引的优点:

(1)提高数据检索的效率,降低数据库的IO成本

(2)通过创建唯一索引,可以保证数据库表中每一行数据的唯一性.

(3)在实现数据的参考完整性方面,可以加速表和表之间的连接。换句话说对于有依赖关系的子表和父表联合查询时,可以提高查询速度。

(4)在使用分组和排序子句进行数据查询时,可以显著减少查询中分组和排序的时间,降低了CPU的消耗.

3.使用索引的缺点:

(1)创建索引和维护索引要 耗费时间 ,并且随着数据量的增加,所耗费的时间也会增加。

(2)索引需要占磁盘空间,除了数据表占数据空间之外,每一个索引还要占一定的物理空间,存储在磁盘上如果有大量的索引,索引文件就可能比数据文件更快达到最大文件尺寸。

(3)虽然索引大大提高了查询速度,同时却会 降低更新表的速度。当对表中的数据进行增加、删除和修改的时候,索引也要动态地维护,这样就降低了数据的维护速度。

三、Innodb中的索引方案:

1.迭代一次:目录项记录的页

目录项其实和用户记录差不多,只不过目录项中的两个列是主键和页号。可以将表示目录项的记录称为目录项记录。可以使用记录头信息里的record_type(0:普通的用户记录;1:目录项记录;2:最小记录;3:最大记录)区分用户记录和目录项记录。

目录项记录和用户记录的不同点:

(1)目录项记录的record_type值是1,而普通用户记录的record_type值为0

(2)目录项记录只有主键值和页的编号两个列,而普通的用户记录的列是用户自己定义的,可能包含很多对。另外还有InnoDB自己添加的隐藏列。

目录项记录和用户记录的相同点:

(1)两者用的是一样的数据页,都会为主键生成Page Directory,从而在按照主键值进行查找时可以使用二分法来加快查询速度。

2.迭代2次:多个目录项记录的页

 3.迭代3次:目录项记录页的目录页

 4.B+Tree:

5.常见索引概念:

(1)聚簇索引:聚簇索引并不是一类单独的索引类型,而是一种数据存储方式(所有的用户记录都存储在叶子节点),也就是所谓的索引即数据,数据即索引。

特点:

a.使用记录主键值的大小记录和页的排序:页内的记录是按照主键的大小顺序排成一个单向链表;各个存放用户记录的值也是根据页中用户记录的主键大小顺序排成一个双向链表;存放目录项记录的页分为不同的层次,在同一层次中的页也是根据页中目录记录项的主键大小顺序排成一个双向链表;

b.B+数的叶子节点存储的是完整的用户记录,包括隐藏列

优点:

a.数据访问更快,因为聚簇索引将索引和数据保存在同一个B+树中,因此从聚簇索引中获取数据比非聚簇索引更快;

b.聚簇索引对于主键的排序查找和范围查找速度非常快

c.按照聚簇索引排列的顺序,查询一定范围数据的时候,由于数据都是紧密相连的,数据库不用从多个数据块中提取数据,所以可以节省大量的IO操作。

缺点:

a.MyISAM不支持聚簇索引,只有InnoDB支持

b.每个MySQL的表只能有一个聚簇索引,一般情况下就是该表的主键

c.innodb表的主键列尽量选用有序的顺序id

d.如果没有定义主键,innodb会选择非空的唯一索引代替,如果没有这样的索引,会隐式的定义一个主键来作为聚簇索引

(2)二级索引(辅助索引,非聚簇索引)

以非主键的列为查找条件,可以在该列上添加索引,此时的索引被称为二级索引

此时使用记录c2列的大小进行记录和页的排序:

a.页内记录是按照c2列的大小顺序排成一个单向链表

b.各个存放用户记录的页也是根据页中记录的c2列的大小顺序排成一个双向链表

c.存放目录项记录的页分为不同的层次,在同一层次中的页也是根据页中的目录项记录的c2列大小顺序拍成一个双向链表

B+树的叶子节点此时存储的并不是完整的用户记录,而是c2列和主键这两个列的值

目录项记录中不再是主键和页号的搭配,而变成c2列和页号的搭配

当按照c2列的值查找到完整的用户记录的话,仍然需要到聚簇索引中再查一遍,这个过程叫做回表。

聚簇索引和非聚簇索引的区别:

a.聚簇索引的叶子节点存储的是数据记录,非聚簇索引的叶子节点存储的是数据位置,非聚簇索引不会影响数据表的物理存储顺序

b.一个表只能有一个聚簇索引,因为只能有一种排序存储的方式,但可以有多个非聚簇索引,也就是多个索引目录提供数据检索

c.使用聚簇索引的时候,数据的查询效率高,但如果对数据进行插入、删除和更新等操作效率比非聚簇索引低。

(3)联合索引

可以以多个列的大小作为排序规则,同时为多个列建立索引。

每条目录项记录都由c2,c3和页号三个部分组成,各条记录先按照c2列的值进行排序,如果记录的c2列相同,则按照c3列的值排序。

B+树的叶子节点处的值由c2,c3和主键列组成。

四、InnoDB的B+树索引的注意事项:

1.根页面的位置万年不动

一个B+树索引的根节点自诞生之日起,变不会再移动。只要对某个表建立一个索引,那么它的根节点的页号便会被记录到某个地方,然后凡是InnoDB存储引擎需要用到这个索引的时候,都会从固定的地方取出根节点的页号,从而来访问这个索引。

2.内节点中目录项记录的唯一性

3.一个页面最少存储2条记录

五、MyISAM中的索引方案:

MyISAM引擎使用B+Tree作为索引结构,叶子节点的data域存放的是数据记录的地址。MyISAM将索引和数据公开存储:

1.将表中的记录按照记录的插入顺序单独存储在一个文件中,称为数据文件。这个文件并不划分为若干个数据页。

2.MyISAM存储引擎会把索引信息另外存储到一个称为索引文件的另一个文件中。MyISAM会单独为表的主键创建一个索引,只不过在索引的叶子节点中存储的不是用户的完整记录而是主键值+数据记录地址的组合。

MyISAM首先按照B+Tree搜索算法搜索索引,如果指定的key存在,则取出其data域的值,然后以该data域的值为地址,读取相应的数据记录。

六、MyISAM与InnoDB对比:

1.在InnoDB存储引擎中,我们只需要根据主键值对聚簇索引进行一次查找就能找到对应的记录,而在 MyISAM 中却需要进行一次回表操作,意味着MyISAM中建立的索引相当于全部都是二级索引。

2. InnoDB的数据文件本身就是索引文件,而MyISAM索引文件和数据文件是分离的,索引文件仅保存数据记录的地址。

3.InnoDB的非聚簇索引data域存储相应记录主键的值,而MyISAM索引记录的是地址。换句话说InnoDB的所有非聚簇索引都引用主键作为data域。

4.MyISAM的回表操作是十分快速的,因为是拿着地址偏移量直接到文件中取数据的,反观InnoDB是通过获取主键之后再去聚簇索引里找记录,虽然说也不慢,但还是比不上直接用地址去访问。

5.InnoDB要求表必须有主键(MyISAM可以没有)。如果没有显式指定,则MySQL系统会自动选择一个可以非空日唯一标识数据记录的列作为主键。如果不存在这种列,则MySQL自动为InnoDB表生成一个隐含字段作为主键这个字段长度为6个字节,类型为长整型。

七、索引的代价:

1.空间上的代价:每建立一个索引都要为它建立一棵B+树,每一棵B+树的每一个节点都是一个数据页,一个页默认会占用 16KB的存储空间,一棵很大的B+树由许多数据页组成,那就是很大的一片存储空间。

2.时间上的代价:每次对表中的数据进行增、删、改操作时,都需要去修改各个B+树索引。而且B+树每层节点都是按照索引列的值从小到大的顺序排序而组成双向链表。不论是叶子节点中的记录,还是内节点中的记录(也就是不论是用户记录还是目录项记录)都是按照索引列的值从小到大的顺序而形成了一个单向链表。而增、删、改操作可能会对节点和记录的排序造成破坏,所以存储引擎需要额外的时间进行一些记录移位,页面分裂、 页面回收等操作来维护好节点和记录的排序。如果我们建了许多索引,每个索引对应的B+树都要进行相关的维护操作,会给性能拖后腿。

八、MySQL数据结构选择的合理性

磁盘的IO操作次数对索引的使用效率至关重要。

1.Hash结构:Hash本身是一个函数,又被称为散列函数,可以大幅提升检索数据的效率。是通过某种确定的算法将输入转变为输出,相同的输入永远可以得到相同的输出,假设输入内容有微小差异,在输出中通常会有不同的结果。哈希函数可能会将两个不同的关键字映射到相同的位置,此时称为碰撞,在数据库中一般采用链接法解决。即将散列到同一个槽位的元素放在同一个链表中。

 2.二叉搜索树:

(1)二叉搜索树的特点:一个节点只能有两个子节点,也就是一个节点的度不能超过2;左子节点处的值<本节点处的值,右子节点处的值≥本节点处的值;

(2)查找规则:

a.如果key大于根节点,则在右子树中进行查找

b.如果key小于根节点,则在左子树中进行查找

c.a.如果key等于根节点,则在直接返回根节点即可

3.平衡二叉搜索树(AVL树):AVL树是一棵空树或者它的左右两个子树的高度差绝对值不超过1,并且左右两个子树都是一棵平衡二叉树。M叉树的高度明显小于二叉树。

4.B-Tree:多路平衡查找树:B树作为多路平衡查找树,它的每一个节点最多可以包括M个子节点,M称为B树的阶。每个磁盘块中包含了关键字和子节点的指针。对于大量的索引数据来说,采用B树的高度要明显小于二叉树的高度。

5.B+Tree:B+树也是一种多路搜索树,是基于B树做出了相应的改进。主流的DBMS都支持B+树的索引方式,更适合文件索引系统。

Hash索引和B+树索引的区别: 

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1467435.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

MyBatis-获取参数

1. 创建MyBatis配置文件模板 编辑完Mybatis核心配置文件和properties文件后&#xff0c;打开IDEA的设置界面&#xff0c;找到Editor中的File and Code Templates&#xff0c;点击加号新增模板。接着将编辑好的核心配置文件中的内容复制粘贴到空白框中&#xff0c;设置好模板名…

Android进阶之旅(第5天)

充实的一天又过去了&#xff0c;今天真的好冷啊&#xff0c;我们这里雪很大&#xff0c;早上最傻逼的决定就是穿了一个短的棉袜出来&#xff0c;漏脚踝&#xff0c;冷成傻子 接下来老规矩&#xff0c;看下昨天计划的完成情况&#xff1a; 今日计划&#xff1a; 1.过bug 2.看…

python 提取PDF文字

使用pdfplumber&#xff0c;不能提取扫描的pdf和插入的图片。 import pdfplumberfile_path rD:\UserData\admindesktop\官方文档\1903_Mesh-Models-Overview_FINAL.pdf with pdfplumber.open(file_path) as pdf:page pdf.pages[0]print(page.extract_text()) # 所以文字prin…

Vulnhub靶机:DC9

一、介绍 运行环境&#xff1a;Virtualbox 攻击机&#xff1a;kali&#xff08;10.0.2.15&#xff09; 靶机&#xff1a;DC9&#xff08;10.0.2.62&#xff09; 目标&#xff1a;获取靶机root权限和flag 靶机下载地址&#xff1a;https://www.vulnhub.com/entry/dc-9,412/…

k8s的svc流量通过iptables和ipvs转发到pod的流程解析

文章目录 1. k8s的svc流量转发1.1 service 说明1.2 endpoints说明1.3 pod 说明1.4 svc流量转发的主要工作 2. iptables规则解析2.1 svc涉及的iptables链流程说明2.2 svc涉及的iptables规则实例2.2.1 KUBE-SERVICES规则链2.2.2 KUBE-SVC-EFPSQH5654KMWHJ5规则链2.2.3 KUBE-SEP-L…

基于JAVA的二手车交易系统 开源项目

目录 一、摘要1.1 项目介绍1.2 项目录屏 二、功能模块2.1 数据中心模块2.2 二手车档案管理模块2.3 车辆预约管理模块2.4 车辆预定管理模块2.5 车辆留言板管理模块2.6 车辆资讯管理模块 三、系统设计3.1 E-R图设计3.2 可行性分析3.2.1 技术可行性分析3.2.2 操作可行性3.2.3 经济…

基于java Springboot实现教务管理系统

基于java Springboot实现教务管理系统《视频版-建议收藏》 博主介绍&#xff1a;5年java开发经验&#xff0c;专注Java开发、定制、远程、文档编写指导等,csdn特邀作者、专注于Java技术领域 作者主页 央顺技术团队 Java毕设项目精品实战案例《1000套》 欢迎点赞 收藏 ⭐留言 文…

cmake 项目。qt5升级 qt6 报错 error: “Qt requires a C++17 compiler 已解决

日常项目开发中。需要对qt5升级到qt6 做cmake兼容配置&#xff0c;在编译中发现&#xff0c;有c 编译环境 报错 2>C:\Qt\6.5.3\msvc2019_64\include\QtCore/qcompilerdetection.h(1226,1): fatal error C1189: #error: "Qt requires a C17 compiler, and a suitable …

容器_Docker ( 06 )

容器_Docker ( 05 ) Kubernetes 资源对象管理 资源对象文件 模板与帮助信息 资源对象文件优势 命令无法实现高级复杂的功能某些资源对象使用命令无法创建方便管理 , 保存 , 追溯历史 资源对象文件太长 , 记不住怎么办 使用命令创建模板查询帮助信息查询官方手册 生成资源…

数据价值在线化丨TiDB 在企查查数据中台的应用及 v7.1 版本升级体验

本文介绍了企查查在数据中台建设中使用 TiDB 的经验和应用。通过从 MySQL 到 TiDB 的迁移&#xff0c;企查查构建了基于 TiDB Flink 的实时数仓框架 &#xff0c;充分利用了 TiDB 的分布式架构、MySQL 兼容性和完善的周边工具等特性&#xff0c;实现了数据的在线化处理。2023 年…

构建生物医学知识图谱from zero to hero (3):生物医学命名实体识别和链接

生物医学实体链接 🤓现在是激动人心的部分。对于NLP和命名实体识别和链接的新手,让我们从一些基础知识开始。命名实体识别技术用于检测文本中的相关实体或概念。例如,在生物医学领域,我们希望在文本中识别各种基因、药物、疾病和其他概念。 生物医学概念提取 在这个例子中…

C++入门学习(三十六)函数的声明

程序是自上而下运行的&#xff0c;比如我下面的代码&#xff1a; #include <iostream> #include<string> using namespace std;int main() { int a1; int b2;int sumaddNumbers(a,b); cout<<sum;return 0; }int addNumbers(int a, int b) { int sum …

一种基于javax.max注解的能力增强技术

目录 现有框架的不足之处 我的改进内容 改进的成果 现有框架的不足之处 Max是javax.validation包中的一个常用注解&#xff0c;用于对传入参数进行最大值校验。但是其校验区间为闭区间&#xff0c;且不支持修改&#xff0c;如&#xff1a;Max(2)&#xff0c;表示表示传入参…

Debug|百度OCR识别错误error_code: 216205

1. 什么错误 在使用百度OCR识别时遇到了错误error_code: 216205。 参照文档【百度OCR文字识别 - API文档 - 错误码】中的描述&#xff0c;是我的图片转base64后大于10M 测试两张图片&#xff1a;923k图片的Base64 大于 10M&#xff1b;2M图片的Base64 小于 10M。 # 电脑上看…

抖音视频下载工具|视频内容提取软件

引言部分&#xff1a; 针对抖音视频下载需求&#xff0c;我们团队自豪推出一款功能强大的工具&#xff0c;旨在解决用户获取抖音视频繁琐问题的困扰。我们通过基于C#开发的工具&#xff0c;让用户能够轻松通过关键词搜索实现自动批量抓取视频&#xff0c;并根据需求进行选择性批…

yolov8-seg dnn调用

接上篇一直更换torch、opencv版本都无法解决这个问题&#xff08;seg调用dnn报错&#xff09;。那问题会不会出在yolov8源码本身呢。yolov8的讨论区基本都看过了&#xff0c;我决定尝试在其前身yolov5的讨论区上找找我不信没人遇到这个问题。很快找到下面的讨论第一个帖子&…

Node.JS入门(day01)

学习源码可以看我的个人前端学习笔记 (github.com):qdxzw/frontlearningNotes 觉得有帮助的同学&#xff0c;可以点心心支持一下哈 一、为什么要学习Node.JS ①可以让其他人访问我们编写的网页 ②为后续的框架学习打基础 二、Node.JS是什么 官方&#xff1a;Node.js是一个…

8.qt5使用opencv的库函数打开图片

1.配置opencv动态库的环境变量 2.在创建的qt工程中加入如下opencv代码&#xff0c;具体代码如下&#xff1a; 使用opencv库函数显示图片

编写LLVM Pass的一个小问题

在阅读官方文档时发现一个很有趣的细节&#xff0c;官方给出了一个测试用例&#xff0c;此处有一个小问题&#xff08;%无法复制&#xff09;。但是我在使用自己编译的ll文件时&#xff0c;我发现该pass无法正常使用。最后经过测试发现是利用-O0编译产生的ll文件有optnone的fla…

数据库管理-第154期 Oracle Vector DB AI-06(20240223)

数据库管理154期 2024-02-23 数据库管理-第154期 Oracle Vector DB & AI-06&#xff08;20240223&#xff09;1 环境准备创建表空间及用户TNSNAME配置 2 Oracle Vector的DML操作创建示例表插入基础数据DML操作UPDATE操作DELETE操作 3 多Vector列表4 固定维度的向量操作5 不…