初始MYSQL数据库(5)—— 索引

找往期文章包括但不限于本期文章中不懂的知识点:

个人主页:我要学编程(ಥ_ಥ)-CSDN博客

所属专栏: MYSQL

目录

索引的概念 

索引选择的数据结构

MySQL中的页的相关知识

索引的分类

主键索引 

普通索引

唯一索引

非聚集索引

回表查询与索引覆盖 

索引的使用

创建主键索引 

使用 alter 修改表结构

增加列

删除列

修改列的数据类型 

修改表名

添加约束 

删除约束 

创建唯一索引

创建外键索引 

创建普通索引 

查看索引 

删除索引 

创建索引的注意事项 


索引的概念 

MySQL中的索引是一种数据结构,它可以帮助数据库高效地查询、更新数据表中的数据。索引通过一定的规则排列数据表中的记录,使得对表的查询可以通过对索引的搜索来加快速度。
MySQL索引类似于书籍的目录,通过指向数据行的位置,可以快速定位和访问表中的数据,比如
汉语字典的目录(索引)页,我们可以按笔画、偏旁部首、拼音等排序的目录(索引)快速查找到需要的字。 

为什么要使用索引呢?索引可以让数据库更加高效地查询、更新数据。

索引选择的数据结构

我们前面知道了MySQL中的索引是一种数据结构,但到底使用的是什么数据结构呢?现在我们就来探讨一下。

首先,上场的是最优秀的数据结构:哈希表。通过学习哈希表,我们知道其存取的时间复杂度是O(1),没有哪一种数据结构快过它。但是由于存在哈希冲突和不能实现范围查找的问题(数据库中 的数据可不是一星半点的),最终被淘汰下场了。

接着,上场的是二叉搜索树。这个既不会存在哈希冲突,还能实现范围查找,并且时间复杂度还能达到O(log N),但可惜的是由于其不能确保树高,并且在特殊情况下的数据是一棵单分支的树,造成其效率低下,最终也被淘汰下场。

再接着就是AVL树和红黑树两兄弟来了,在汲取上次教训的基础上,这两兄弟实现了升级和改版之后,确实保证了树高(红黑树不算严格保证树高)。但是由于在插入数据时要进行频繁的旋转和在数据量非常大的情况下,树高还是不能保证(父节点最多只能有两个孩子)。因此最终也是很遗憾地被淘汰了。

注意:由于数据是存储在磁盘中,如果想要获取数据的话,就得需要去进行磁盘的IO,而磁盘的IO效率是十分低下的,因此在设计索引时,应当减少磁盘的IO。而我们在获取二叉树的数据时,每次都得去进行磁盘的IO,并且一次磁盘的IO只获取一层的节点数据(内存较小,无法一次性把磁盘中的数据全部读取到内存中),因此当树高非常高时(数据量过大),在查找数据的过程中,磁盘的IO次数也就非常多,这也就直接导致了查找的效率十分低下了。

通过上面的标准,AVL树和红黑树两兄弟继续奋发图强进行改造和升级。既然你说树的层数过高导致效率低下,那么我每个父节点就允许可以有若干个孩子节点,这样就可以减少层数啦!这就是B树,也被称为N叉树。可惜这个面试官还是太挑了(毕竟人家MySQL是"大公司"嘛),最终B树没有被选上,而是选择它的加强版B+树。我们下面就来看看这个B+树比B树好在哪里。

B+树有以下特点:

1、 非叶子节点并未储存数据,只是把当作索引用的,叶子结点才是存储的真实数据;

2、叶子节点之间构成了一个双向链表;

3、查找任意数据的时间复杂度都是相同的。因为所有的数据都是存储在叶子结点,即查找数据都是查找到叶子结点。

MySQL中的页的相关知识

在学习页之前,得先知道 .ibd 文件,.ibd 文件是 InnoDB存储引擎创建表时,产生的独立表空间文件名后缀。而每一个独立表空间文件都是有很多的页组成的。页是内存与磁盘交互的最小单元,默认大小为 16KB,每次内存与磁盘的交互至少读取一页,所以在磁盘中每个页内部的地址都是连续的。页也分为很多种:数据页(存储真实数据的)、索引页(存储索引信息的)......这些页内部是由页头、页尾、页主体(由很多数据行组成)组成的。页头中存储了上一页号和下一页号的地址,也就是页与页之间构成了双向链表的关系。其实B+树中的节点就是由若干个页组成的。页主体中除了存储真实数据的数据行之外,还有两个特殊的数据行:最大行与最小行。这两个行是被当成链表的单链表的头和尾使用的。即页主体的数据行其实是一个单向链表。而最小行就被当成了单链表的头,最大行就被当成了单链表的尾。并且当页主体中的数据行也会进行分组(一组中当数据超过8条时,便会重新开始分配新的组),而最小行会被单独当作一组,最大行是在最后一组(但不是单独的)。并且随着分组的创建也会产生一个页目录(用于对数据行进行更快的查找),这个页目录是由槽组成的,即每个分组对应着一个槽。槽中记录的是对应组的最后一个数据行的索引信息。最后页主体中还有一个数据页头,记录的是当前页保存数据的相关信息。即保存的主体页的相关数据信息。

上面都是为索引做的铺垫,下面我们才开始索引的学习。

索引的分类

主键索引 

当在表中定义了一个主键 primary key时,会自动创建一个索引,InnoDB会使用其作为主键索引,也被称为聚集索引或者聚簇索引。 

普通索引

 为了提高查询的效率,针对查询平凡的列创建的索引。

唯一索引

当在表中定义了一个唯一键 unique 时,会自动创建唯一索引。唯一索引在普通索引的基础上避免了值重复出现。

注意:

1、每创建一个索引,都会生成一棵索引树,同样也是会占用磁盘空间的。并且索引树越多,对增删改的效率影响就越大。因为要去维护索引树的相关信息。 

2、当一个表中没有创建主键时,会用第一个unique 和 not null 的列作为聚集索引。如果找不到的话,InnoDB会自增一个列为聚集索引,但是我们是无权使用的。

非聚集索引

除了聚集索引以外的索引都是被称为非聚集索引的或者是二级索引。

回表查询与索引覆盖 

当我们使用 select 语句进行查询操作时,如果在索引信息部分(聚集索引)找到了要查询的信息,那么就没必要继续查询了,直接返回查询的结果即可。这就叫索引覆盖。而当索引信息中没有我们要查找的信息时,就需要去存储完整数据的地方去查询相关信息,这就叫回表查询。

索引的使用

知道了索引的分类和相关信息,接下来,我们就开始创建和使用索引。

创建主键索引 

前面我们学习了,创建主键、外键、唯一键时都会自动生成索引,因此在创建这三种索引时,都只是在创建其相关约束。 

-- 方式一
create table student (id bigint primary key auto_increment,name varchar(50)
);-- 方式二
create table student2 (id bigint auto_increment,name varchar(50),primary key (id) -- 这里指定多个列,使用复合主键的方式
);-- 方式三
create table student3 (id bigint,name varchar(50)
);
alter table student3 add primary key (id);
alter table student3 modify id bigint auto_increment;

第三种方式,是一种修改表结构的方式。 现在就来详细学习一下。

使用 alter 修改表结构

增加列

语法:

ALTER TABLE table_name
ADD column_name datatype;

例如:

-- 往student表中添加class_id这样一列,数据类型为bigint
alter table student add class_id bigint;

删除列

语法: 

ALTER TABLE table_name
DROP column_name;

例如:

-- 将student表中列名为class_id的列删除
alter table student drop class_id:

修改列的数据类型 

语法: 

ALTER TABLE table_name
MODIFY column_name datatype;

例如:

-- 将student表中列名为name的列,其数据类型修改为 varchar(20)
alter table student modify name varchar(20);

修改表名

语法:

ALTER TABLE old_table_name 
RENAME TO new_table_name;

例如:

-- 将表名为student的表,其名字修改为stu
alter table student rename to stu;

添加约束 

语法:

-- 添加主键约束和唯一约束比较简单,都是下面的语法
ALTER TABLE table_name 
ADD PRIMARY KEY (column_name);ALTER TABLE table_name 
ADD UNIQUE (column_name);

例如:

-- 为student表的id列添加为主键
alter table student add primary key (id);

删除约束 

语法:

ALTER TABLE table_name 
DROP CONSTRAINT constraint_name;

例如:

-- 将student表中的主键约束删除(包括复合主键)
alter table student drop constraint primary key;

创建唯一索引

-- 方式一
create table class (id bigint primary key auto_increment,name varchar(30) unique
);-- 方式二
create table class2 (id bigint primary key auto_increment,name varchar(30),unique key (name) -- 注意这里的写法是unique key
);-- 方式三
create table class3 (id bigint primary key auto_increment,name varchar(30)
);
alter table class3 add unique (name);

创建外键索引 

-- 方式一
create table class (id bigint primary key auto_increment,name varchar(30) unique
);create table student (id bigint primary key auto_increment,name varchar(50),class_id bigint,foreign key (class_id) references class(id)
);

 由于使用 alter 新增外键比较麻烦,因此也就导致了创建外键索引时,也会比较麻烦。

 使用 alter 语句创建外键 (索引) 语法:

ALTER TABLE child_table
ADD CONSTRAINT fk_name
FOREIGN KEY (child_column)
REFERENCES parent_table(parent_column)

参数说明: 

child_table:子表名称。
fk_name :外键约束的名称,可以自定义。
child_column:子表中要作为外键的列名。
parent_table :父表名称。
parent_column :父表中被引l用的列名。

例如: 

-- 指定外键约束名称
alter table student2 add constraint fk_name 
foreign key (class_id) references class(id);-- 不指定外键约束名称
alter table student2 add foreign key (class_id) references class(id);

有上面两种创建外键 (索引) 的方式。区别如下所示:

创建普通索引 

-- 方式一
create table student (id bigint primary key auto_increment,name varchar(50),sno varchar(20),index (sno)
);-- 方式二
create table student2 (id bigint primary key auto_increment,name varchar(50),sno varchar(20)
);
alter table student2 add index (sno);-- 方式三
create table student3 (id bigint primary key auto_increment,name varchar(50),sno varchar(20)
);
create index index_student3_sno on student3(sno);

方式三使用创建索引的方式,而方式一和方式二都是添加索引的方式。

上面都是创建一个单独的索引,现在我们开始学习复合索引。

-- 方式一
create table student (id bigint primary key auto_increment,name varchar(50),sno varchar(20),class_id bigint,index (sno, class_id)
);-- 方式二
create table student2 (id bigint primary key auto_increment,name varchar(50),sno varchar(20),class_id bigint
);
alter table student2 add index (sno, class_id);-- 方式三
create table student3 (id bigint primary key auto_increment,name varchar(50),sno varchar(20),class_id bigint
);
create index index_student3_sno on student3(sno, class_id);

当然,我们刚刚学习的索引都是可以创建复合索引的,这里只展示普通索引的示例。 

查看索引 

既然我们创建了索引,那么就应该可以查看索引的相关信息。 

语法:

-- 方式一
show index from table_name;-- 方式二
show keys from table_name;

例如:

-- 查看student表的索引信息
show index from student;-- 查看student表的索引信息
show keys from student;

查询结果都是如下所示: 

注意:虽然这里索引的数据类型显示的是BTREE,但实际上是B+树。 

如果只有查看简明信息的话,就是使用我们前面学习的查看表结构的方法。 

唯一键对应的就是 UNI。 

注意:查看复合索引的详细信息时,键名都是指第一列的(从左往右)。如下所示:

删除索引 

 删除的索引中分为两种:1、主键索引;2、其他索引。

删除主键索引的语法:

alter table table_name drop primary key;

注意:再删除主键时,不能有自增属性,否则会报错。如果存在自增属性的话,得先把自增属性给删除,再去删除主键。

删除其他索引的语法:

alter table table_name drop index 索引名;

注意这里的索引名不是列名,而是我们在创建索引时取的名字。 

创建索引的注意事项 

1、索引应该创建在高频查询的列上;

2、索引需要占用额外的存储空间,所以索引不是越多越好;

3、对表进行插入、更新和删除操作时,同时也会修索引,可能会影响性能(在数据过多的情况下);

4、创建过多或不合理的索引会导致性能下降,需要谨慎选择和规划索引。

好啦!本期 初始MYSQL数据库(5)—— 索引 的学习之旅就到此结束啦!我们下一期再一起学习吧!

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Qt 边框border - qss样式

border属性 实际上,border并不是一个单独的属性,在Qt样式表中,它通常指的是一系列与边框相关的属性的组合。然而,你也可以在一条样式规则中一次性设置所有这些值,如下所示: QPushButton { border: 2px sol…

Layout 布局组件快速搭建

文章目录 设置主题样式变量封装公共布局组件封装 Logo 组件封装 Menu 菜单组件封装 Breadcrumb 面包屑组件封装 TabBar 标签栏组件封装 Main 内容区组件封装 Footer 底部组件封装 Theme 主题组件 经典布局水平布局响应式布局搭建 Layout 布局组件添加 Layout 路由配置启动项目 …

Unity实战案例全解析:PVZ 植物放置分析

前篇:Unity实战案例全解析:PVZ 植物卡片状态分析-CSDN博客 植物应该如何从卡牌状态转为实物? 其实就只需要考虑两个步骤加一个后续处理: 1.点击卡牌后就实例化 需要一个植物状态枚举,因为卡牌分为拿在手上和种植下…

道路裂缝,坑洼,病害数据集-包括无人机视角,摩托车视角,车辆视角覆盖道路

道路裂缝,坑洼,病害数据集 包括无人机视角,摩托车视角,车辆视角 覆盖道路所有问题 一共有八类16000张 1到7依次为: [横向裂缝, 纵向裂缝, 块状裂缝, 龟裂, 坑槽, 修补网状裂缝, 修补裂缝, 修补坑槽] 道路病害(如裂缝、…

MQ(RabbitMQ)笔记

初识MQ 同步调用优缺点 异步调用优缺点 总结: 时效性要求高,需要立刻得到结果进行处理--->同步调用 对调用结果不关心,对性能要求高,响应时间短--->异步调用

人工智能和大模型的简介

文章目录 前言一、大模型简介二、大模型主要功能1、自然语言理解和生成2、文本总结和翻译3、文本分类和信息检索4、多模态处理三、大模型的技术特性1、深度学习架构2、大规模预训练3、自适应能力前言 随着技术的进步,人工智能(Artificial Intelligence, AI)和机器学习(Mac…

NPM如何切换淘宝镜像进行加速

什么是淘宝镜像NPM? 淘宝镜像NPM和官方NPM的主要区别在于服务器的地理位置和网络访问速度。淘宝镜像NPM是由淘宝团队维护的一个npm镜像源,主要服务于中国大陆用户,提供了一个国内的npm镜像源,地址为 https://registry.npmmirror.…

论文阅读 - SELF-REFINE: Iterative Refinement with Self-Feedback

https://arxiv.org/pdf/2303.17651 目录 Abstract Introduction 2 Iterative Refinement with SELF-REFINE Evaluation 3.1 Instantiating SELF-REFINE 3.2 Metrics 3.3 Results Abstract 与人类一样,大型语言模型(LLMs)并非总能在首次…

【有啥问啥】深入浅出马尔可夫链蒙特卡罗(Markov Chain Monte Carlo, MCMC)算法

深入浅出马尔可夫链蒙特卡罗(Markov Chain Monte Carlo, MCMC)算法 0. 引言 Markov Chain Monte Carlo(MCMC)是一类用于从复杂分布中采样的强大算法,特别是在难以直接计算分布的情况下。它广泛应用于统计学、机器学习…

【python设计模式2】创建型模式1

目录 简单工厂模式 工厂方法模式 简单工厂模式 简单工厂模式不是23中设计模式中的,但是必须要知道。简单工厂模式不直接向客户端暴露对象创建的细节,而是通过一个工厂类来负责创建产品类的实例。简单工程模式的角色有:工厂角色、抽象产品角…

Redis——常用数据类型string

目录 常用数据结构(类型)Redis单线程模型Reids为啥效率这么高?速度这么快?(参照于其他数据库) stringsetgetMSET 和 MGETSETNX,SETEX,PSETEXincr,incrby,decr…

go多线程

1、简单使用(这个执行完成,如果进程执行比较久,这里不会等待它们结束) package mainimport "time"func main() {go func() {println("Hello, World!")}()time.Sleep(1 * time.Second) }2、wg.Add(数量)使用&…

STM32 定时器 输入捕获

定时器输入捕获 1 工作原理1.1 单个通道的工作原理 2 输入滤波2.1 输入滤波原理 3 边沿检测3.1 边沿检测3.2 信号选择 4 分频5 通道使能 1 工作原理 1.1 单个通道的工作原理 2 输入滤波 2.1 输入滤波原理 fck_INT:内部时钟频率,当PCLKx_Pre为1时&…

prometheus 集成 grafana 保姆级别安装部署

前言 本文 grafana 展示效果只需要 prometheus node_exporter grafana 其他的选择安装 环境和版本号 系统: CentOS 7.9 prometheus: 2.54.1 pushgateway: 1.9.0 node_exporter: 1.8.2 alertmanager: 0.27.0 grafana:11.2.0 官网:https://prometheus.io/ 下载地址:h…

软件测试 | APP测试 —— Appium 的环境搭建及工具安装教程

大家应该都有同一种感觉,学习appium最大的难处之一在于环境的安装,安装流程比较繁琐,安装的工具和步骤也较多,以下是基于Windows系统下的Android手机端的安装流程。就像我们在用Selenium进行web自动化测试的时候一样,我…

Gin渲染

HTML渲染 【示例1】 首先定义一个存放模板文件的 templates文件夹&#xff0c;然后在其内部按照业务分别定义一个 posts 文件夹和一个 users 文件夹。 posts/index.tmpl {{define "posts/index.tmpl"}} <!DOCTYPE html> <html lang"en">&…

计算机毕业设计 视频点播网站 Java+SpringBoot+Vue 前后端分离 文档报告 代码讲解 安装调试

&#x1f34a;作者&#xff1a;计算机编程-吉哥 &#x1f34a;简介&#xff1a;专业从事JavaWeb程序开发&#xff0c;微信小程序开发&#xff0c;定制化项目、 源码、代码讲解、文档撰写、ppt制作。做自己喜欢的事&#xff0c;生活就是快乐的。 &#x1f34a;心愿&#xff1a;点…

day22JS-npm中的部分插件使用方法

1. 静态资源目录 静态资源目录就是访问服务器的某些路劲时候&#xff0c;服务器可以吐出一个写好的指定页面。 实现思路&#xff1a; 1、先判断要找的路径是否是文件&#xff0c;如果是文件&#xff0c;就加载发给对方。 2、如果是文件夹&#xff0c;找到这个文件夹所在路径中…

Spring Boot基础

项目创建 项目启动 请求响应 RestController 1.返回值处理 RestController&#xff1a;这个注解结合了Controller和ResponseBody的功能。它默认将所有处理请求的方法的返回值直接作为响应体内容返回&#xff0c;主要用于构建RESTful API。返回的数据格式通常是JSON或XML&…

Linux:软件包管理器 yum和编辑器-vim使用

hello&#xff0c;各位小伙伴&#xff0c;本篇文章跟大家一起学习《Linux&#xff1a;软件包管理器 yum和编辑器-vim使用》&#xff0c;感谢大家对我上一篇的支持&#xff0c;如有什么问题&#xff0c;还请多多指教 &#xff01; 如果本篇文章对你有帮助&#xff0c;还请各位点…