03.MySQL——索引和事务

news2024/11/24 16:54:07

索引

索引的概念

  • 索引可以提高数据库的性能
  • 不用加内存,不用改程序,不用调sql,只要执行正确的 create index ,查询速度就可能提高成百上千倍。
  • 但是查询速度的提高以插入、更新、删除的速度为代价。
  • 索引的价值在于提高一个海量数据的检索速度。

索引分类

  • 主键索引(primary key)
  • 唯一索引(unique)
  • 普通索引(index)
  • 全文索引(fulltext)

索引的应用场景

当存在一个10000000条记录的数据库表时,查询员工编号为998877的员工select * from EMP where empno=998877; 耗时大约在5S,在实际公网服务器项目中,面对高并发访问就很可能死机。

当创建索引后,alter table EMP add index(empno); 查询效率就会大幅度提高,减少上述场景发生的可能性。


索引的理解

前言

  1. mysqld本质是一个运行在OS上的进程。
  2. 对MySQL数据进行操作本质上是对文件进行操作。
  3. 任何的磁盘数据在进程中操作本质都必须在内存中进行。
  4. MySQL在启动的时候,会预先申请一部分内存空间,通过文件系统把文件load到缓冲区中。
  5. MySQL进行保存和IO的基本单位(Page)是16KB,OS管理内存的基本单位是4KB,磁盘设备的基本单位是512字节(扇区大小)。
  6. 根据局部性原理,有很大概率能访问到预加载的数据,所以MySQL的IO交互是 Page相较于用多少,加载多少的方案而言可以提高效率。
  7. MySQL内部会存在大量的page,管理好这些page,就需要先描述再组织。
  8. 索引的基础就是采用B+树的数据结构来组织这些page。

单页Page

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-TQNC7o2K-1689765817736)(C:\Users\11794\AppData\Roaming\Typora\typora-user-images\image-20230719142742950.png)]

  • MySQL 中的Page都是 16KB ,使用 prev 和 next 构成双向链表。链表的特点是增删快,查询修改慢,所以优化查询的效率是必须的。

  • 如果有主键的存在, MySQL 会默认按照主键给我们的数据进行排序,数据是有序且彼此关联的,插入数据时排序的目的就是为了方便引入页目录从而优化查询的效率

  • 目录是一种“空间换时间的做法” ,提高了查找的效率。


    多页Page

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-G52Zugve-1689765817737)(C:\Users\11794\AppData\Roaming\Typora\typora-user-images\image-20230719143306309.png)]

    • MySQL 中每一页的大小只有 16KB ,单个Page大小固定,但是随着数据量不断增大,16KB 不可能存下所有的数据,那么必定会有多个页来存储数据。

    • 给Page页也带上目录,使用一个目录项来指向某一页,而这个目录项存放的就是将要**指向的页中存放的最小数据的键值。**通过比较找到要访问的那个Page,进而通过指针找到下一个Page 。

    • 目录页的本质也是页,普通页中存的数据是用户数据,而目录页中存的数据是下级Page的最小键值和普通页的地址映射。

    • 查找的时候,自顶向下找,只需要加载部分目录页到内存,即可完成算法的整个查找过程,大大减少了IO次数。

    • 多个page构成B+树,全部的数据都在叶子节点,非叶子节点只保存键值和Page指针。B+树中的需要全部load到内存,mysql会按需load。

    • 索引的本质就是通过B+树的数据结构将表中的数据根据用户指定的关键字组织起来,提高查找的效率


    为何选择B+,不选择B树

    • B树节点既有数据又有Page指针,而B+只有叶子节点有数据,其他目录页只有键值和Page指针,B+叶子节点全部相连,而B树不会。

    • 目录页不存储数据可以让一个目录页管理更多的page,使得树更矮,减少IO次数。并且叶子节点相连,更便于进行范围查找。


    聚簇索引和非聚簇索引

    聚簇索引:用户数据与索引数据在一起索引方案,叫做聚簇索引,例如:InnoDB 存储引擎。

    非聚簇索引: 索引Page和数据Page分离,也就是叶子节点没有数据,只有对应数据的地址,叫做非聚簇索引,例如: MyISAM 存储引擎。


索引操作

创建主键索引

-- 在创建表的时候,直接在字段名后指定 primary key
create table user1(id int primary key, name varchar(30));
-- 在创建表的最后,指定某列或某几列为主键索引
create table user2(id int, name varchar(30), primary key(id));
create table user3(id int, name varchar(30));
-- 创建表以后再添加主键
alter table user3 add primary key(id);

主键索引的特点:

  • 一个表中最多有一个主键索引
  • 主键索引的效率高
  • 创建主键索引的列,它的值不能为null
  • 主键索引的列基本上是int

创建唯一键索引

-- 在表定义时,在某列后直接指定unique唯一属性。
create table user4(id int primary key, name varchar(30) unique);
-- 创建表时,在表的后面指定某列或某几列为unique
create table user5(id int primary key, name varchar(30), unique(name));
-- 创建表以后再添加唯一键
create table user6(id int primary key, name varchar(30));
alter table user6 add unique(name);

唯一索引的特点:

  • 一个表可以有多个唯一索引
  • 查询效率高
  • 唯一索引列数据不能重复
  • 如果一个唯一索引上指定not null = 主键索引

创建普通索引

create table user8(id int primary key,
    name varchar(20),
    email varchar(30),
    index(name) --在表的定义最后,指定某列为索引
);
create table user9(id int primary key, name varchar(20), email varchar(30));
alter table user9 add index(name); --创建完表以后指定某列为普通索引
create table user10(id int primary key, name varchar(20), email varchar(30));
-- 创建一个索引名为 idx_name 的索引
create index idx_name on user10(name);

普通索引的特点:

  • 一个表中可以有多个普通索引,普通索引在实际开发中用的比较多
  • 如果某列需要创建索引,但是该列有重复的值,那么我们就应该使用普通索引

索引创建原则

  • 频繁作为查询条件的字段应该创建索引
  • 唯一性太差的字段不适合单独创建索引
  • 更新非常频繁的字段不适合作创建索引
  • 不会出现在where子句中的字段不该创建索引

创建全文索引

当对文章字段或有大量文字的字段进行检索时,会使用到全文索引。MySQL全文索引的存储引擎必须是MyISAM,而且默认的全文索引支持英文,不支持中文。如果对中文进行全文检索,可以使用sphinx。


查询索引

  • show keys from 表名;
  • show index from 表名;
  • desc 表名;

删除索引

  • 删除主键索引:alter table 表名 drop primary key;
  • 删除其他索引: alter table 表名 drop index 索引名;
  • drop index 索引名 on 表名

事务

事务的概念

  • 事务就是一组在逻辑上存在相关性的sql语句集合,作为一个整体,要么全部成功,要么全部失败
  • 事务不是数据库软件天然存在的,而是为了简化工作,数据库提供的机制,不需要我们去考虑各种各样的潜在错误和并发问题 。
  • 事务主要用于处理操作量大,复杂度高的数据,事务规定不同的客户端看到的数据是不相同的
  • mysqld提供了事务机制,同时就会对多个事务采用先描述,再组织的方式进行管理。

事务的属性

  • MySQL 数据库不止你一个事务在运行,同一时刻,甚至有大量的请求被包装成事务,在向 MySQL 服务器发起事务处理请求。而每条事务至少一条 SQL ,这样如果大家都访问同样的表数据,在不加保护的情况就绝对会出现问题。所以,一个完整的事务绝对不是简单的 sql 集合,还需要满足如下四个属性 :
  • 原子性:一个事务 中的所有操作,要么全部完成,要么全部不完成,不会结束在中间某个环节。事务在执行过程中发生错误,会被回滚到事务开始前的状态,就像这个事务从来没有执行过一样。
  • 持久性:事务处理结束后,对数据的修改就是永久的,即便系统故障也不会丢失。
  • 隔离性:数据库允许多个并发事务同时对其数据进行读写和修改的能力,隔离性可以防止多个事务并发执行时由于交叉执行而导致数据的不一致。事务隔离分为不同级别,包括读未提交、读提交、可重复读和串行化。
  • 一致性:在事务开始之前和事务结束以后,数据库的完整性没有被破坏。这表示写入的资料必须完全符合所有的预设规则,这包含资料的精确度、串联性以及后续数据库可以自发性地完成预定的工作。
  • 前三种属性是手段,而一致性是目的。

事务的版本支持

  • MySQL 中只有使用了 Innodb 数据库引擎的数据库或表才支持事务, MyISAM 不支持。

事务提交方式

事务的提交方式常见的有两种:

  • 自动提交
  • 手动提交

查看事务提交方式

show variables like 'autocommit';

用 SET 来改变 MySQL 的自动提交模式

SET AUTOCOMMIT=0;  #SET AUTOCOMMIT=0 禁止自动提交 #SET AUTOCOMMIT=1 开启自动提交

事务的操作

start transaction/begin;——开始一个事务

rollback; ——回滚事务,默认回滚到最开始

savepoint XXX;——再任意位置创建一个回滚点

rollback to XXX; ——回滚到回滚点所在的位置

start transaction/begin;——开始一个事务

commit——提交事务。

  • 只要输入begin/start transaction,事务必须通过commit提交才会持久化,与是否设置set autocommit无关。
  • 事务可以手动回滚,当操作异常,MySQL也会自动回滚。
  • 对于 InnoDB 每一条 SQL 语言都默认封装成事务,按照autocommit的值决定是否自动提交。
  • 如果一个事务被提交了,则不可以回退

事务隔离级别

MySQL服务可能会同时被多个客户端进程(线程)访问,访问的方式以事务方式进行。在数据库中,为了保证事务执行过程中尽量不受干扰,就需要一个重要特征:隔离性。在保证数据安全的情况下,允许事务受不同程度的干扰,就有了一种重要特征:隔离级别

  • 读未提交【Read Uncommitted】: 所有的事务都可以看到其他事务没有提交的执行结果。但是相当于没有任何隔离性,也会有很多并发问题,如:脏读,幻读,不可重复读。
  • 读提交【Read Committed】 :一个事务只能看到其他的已经提交的事务。这种隔离级别会引起不可重复读,即一个事务执行时,如果多次 select 可能得到不同的结果。
  • 可重复读【Repeatable Read】: 这是 MySQL 默认的隔离级别,它确保一个事务内部,在执行
    中,多次读取操作数据时会看到同样的数据,但是会有幻读问题(MySQL解决了幻读的问题)。
  • 串行化【Serializable】: 这是事务的最高隔离级别,它通过强制事务排序,使之不可能相互冲突,从而解决了幻读的问题。它在每个读的数据行上面加上共享锁,但是可能会导致超时和锁竞争。

脏读

  • 一个事务在执行中,读到另一个执行中事务的更新但是未commit的数据,这种现象叫做脏读。

不可重复读

  • 同一个事务内,同样的读取,在不同的时间段,读取到了不同的值,这种现象叫做不可重复读。

幻读

  • 一般的数据库在可重复读情况的时候,无法屏蔽其他事务insert的数据,导致多次查找时,会多查找出来新的insert记录,这种现象,叫做幻读。

总结

  • 其中隔离级别越严格,安全性越高,但数据库的并发性能也就越低,往往需要在两者之间找一个平衡点。
  • 不可重复读的重点是修改和删除:同样的条件,你读取过的数据,再次读取出来发现值不一样。
  • 幻读的重点在于新增:同样的条件, 第1次和第2次读出来的记录数不一样。
  • 事务也有长短事务这样的概念,事务间互相影响,指的是事务在并行执行的时候,即都没有commit的时候,互相影响。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-DZHiy6up-1689765817737)(C:\Users\11794\AppData\Roaming\Typora\typora-user-images\image-20230719161526460.png)]

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

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

相关文章

SOT封装特点和优势,sot23封装尺寸

SOT封装是一种常用的集成电路封装类型,常见的SOT封装类型包括3引脚(如SOT-23)、4引脚(如SOT-89和SOT-223)和6引脚(如SOT-363),可以适应不同的电路设计和功能要求。具有以下特点和优势…

Springboot配置相关问题

目录 一.ConfigurationProperties注解补充知识: 二、松散绑定三、常用计量单位的应用四、数据校验补充知识 一.ConfigurationProperties注解 使用该注解可以为Bean绑定application.yml中的属性值。以下就是使用ConfigurationProperties注解的示例 项目结构 Serve…

Halcon机器视觉-15种常用缺陷检测实例

一、Halcon 15种常用缺陷检测实例分享 缺陷检测是一种通过计算机视觉技术来检测产品制造过程中的缺陷的方法。该技术可以检测出产品表面的缺陷,如裂纹、凹陷、划痕、气泡等,并且可以实时监测和诊断制造过程中的问题。在制造业中,机器视觉缺陷…

spring复习:(45)使用TransactionProxyFactoryBean来实现事务时,发生异常时,事务是怎么回滚的?

TransactionAspectSupport类: invokeWithinTransaction方法发生异常时会调用completeTransactionAfterThrowing protected void completeTransactionAfterThrowing(Nullable TransactionInfo txInfo, Throwable ex) {if (txInfo ! null && txInfo.getTrans…

Java Mybatis拓展03

0目录 1.MyBatis当实体类和数据库字段名不对应 2.多表查询 1.MyBatis当实体类和数据库字段名不对应 方法2 测试 多表查询 加入子标签association 模糊查询 加入Address 对象 三表联查 2.五表联查 测试

微服务Day3——Nacos配置管理\Feign远程调用\Gateway网关

一、Nacos配置管理 1、统一配置管理 当微服务部署的实例越来越多,达到数十、数百时,逐个修改微服务配置就会让人抓狂,而且很容易出错。我们需要一种统一配置管理方案,可以集中管理所有实例的配置。 Nacos一方面可以将配置集中管理…

朝花夕拾 - 2023 精神错乱记录

jsliang 的精神错乱记录,一点 2023 小思考。 也许我们曾偏离航道,但请不要放弃抵达终点 前言 在 2020.11 过来珠海,来到金山工作 2 年半的时间里: 在工作上,更换了 3 个小团队,达到了每年一换在工作上&…

我国版式文档格式OFD前端WEB展示之EasyOFD

EasyOFD an ofd file web shower 一个在web端展示ofd文件的控件,该控件基于CANVAS绘制。 该控件使用了以下外部程序 1)jszip:解决解压文件。 2)x2js: 解决XML文件到JS转换 3)easyjbig2: 解决ofd内部使用jb2文件存储的…

A Survey on Time-Series Pre-Trained Models

本文是LLM系列的文章,针对《A Survey on Time-Series Pre-Trained Models》的翻译。 时间序列预训练模型综述 摘要1 引言2 背景2.1 时间序列挖掘任务2.1.1 时间序列分类2.1.2 时间序列预测2.1.3 时间序列聚类2.1.4 时间序列异常检测2.1.5 时间序列推测 2.2 深度学习…

手打 小份 kubernetes v1.27.3 集群

文章目录 1. 准备2. yum3. 安装 ansible4. 互信5. hosts6. 关闭防火墙、swap、selinux7. 配置系统文件句柄数8. 启用ipvs9. 修改内核参数10. 安装 containerd11. 安装nerdctl12. kubernetes yum13. 部署 kubernetes13.1 安装工具13.2 初始化配置 14. 部署 master15. 部署 node1…

【微信机器人开发

现在并没有长期免费的微信群机器人,很多都是前期免费试用,后期进行收费,或者核心功能需要付费使用的。 这时如果需要群机器人帮助我们管理群聊,建议大家使有条件的可以自己开发微信管理系统。了解微信群机器人的朋友都知道&#x…

iTerm复制粘贴出现00~ 01~

问题 iTerm2中复制粘贴出现如下现象 解决 命令行直接输入printf \e[?2004l 回车

SSH跳转/SCP复制远程目标服务器的高阶使用

在日常开发和运维的过程中,我一般是使用Xshell的工具对linux服务器的相关操作。我说一下我写这篇文章的背景:甲方因为安全需要,给了一台可以通过vpn访问的跳板机,通过这台跳板机去操作另外的十多台应用服务器,那么肯定…

零花钱项目---赚钱

流量卡代理推广 172号卡分销系统开启代理注册,月入过万不是梦 适合人群每天随便发发信息,就能轻松变现。平台的可靠 什么是172号卡分销系统 172号卡分销系统是一个专门用于手机流量卡销售的平台。这个系统主要针对中国的三大运营商——中国移动、中国…

DirectX12(D3D12)基础教程(二十二) ——HDR IBL 等距柱面环境光源加载和解算及 GS 一次性渲染到 CubeMap

前序文章目录 DirectX12(D3D12)基础教程(一)——基础教程 DirectX12(D3D12)基础教程(二)——理解根签名、初识显存管理和加载纹理、理解资源屏障 DirectX12(D3D12&…

并发请求gitlab接口报错500 Internal Server Error

配置环境 Gitalb 14.9 由docker搭建,使用的数据库是内置的postgresql 问题背景 近期发现自研系统在请求调用 gitlab 的 api 接口时,尤其是并发请求同一资源时,我这里是并发创建subgroup这个资源,会得到500的报错,起…

ONNX 推理,精度下降

先看代码: img cv2.imread("65.jpg") img1 img.copy() img2 img.copy() img1 - 112 img1 img1.astype(np.float32) img2 np.float32(img2) img2 - 112 现象:在使用 img1 这种处理方式时,推理结果异常,起码掉点…

SpringBoot错误: 找不到或无法加载主类

1.一般出现这种情况都是配置文件application.properties出现的问题 2.可以尝试 maven clean install 以及rebuild project 3.删除项目里.idea文件 重新导入至IDEA编辑器 选择Maven项目 配置好maven.xml 后重新导入

【Linux】进程间通信——管道/共享内存

文章目录 1. 进程间通信2. 管道匿名管道命名管道管道的特性管道的应用:简易的进程池 3. System V共享内存共享内存的概念共享内存的结构共享内存的使用代码实现 1. 进程间通信 进程间通信(Inter-Process Communication,简称IPC)是…

解锁医疗新时代!互联网医院系统源码助您开启智慧就医新体验

互联网医院系统软件开发之后具有许多优势,下面将介绍其中一些。   提供便利的就医方式:互联网医院系统软件可以让患者享受在线诊疗的便利。患者可以通过手机或电脑随时随地进行在线挂号、在线咨询、在线复诊等操作,不再受制于时间和地点的限…