「MySQL」索引事务

🎇个人主页:Ice_Sugar_7
🎇所属专栏:数据库
🎇欢迎点赞收藏加关注哦!

索引&事务

  • 🍉索引
    • 🍌特点
    • 🍌通过 SQL 操作索引
    • 🍌底层数据结构
  • 🍉事务
    • 🍌特性

🍉索引

在数据库中,进行条件查询的时候经常需要遍历表。
我们知道遍历一遍的时间复杂度是O(N),不过由于数据库是把数据存储在硬盘上的,硬盘上的 IO 比内存中的慢很多,即此处的 O(N) 比我们通常说的 O(N) 要慢很多
因此,我们可以给数据库引入索引,提高查询的速度

🍌特点

  1. 加快查询的速度
  2. 索引本身是一定的数据结构,也要占据存储空间
  3. 当我们进行新增、删除、修改的时候,也需要对索引进行更新,这就有额外的开销

由索引的特点,我们不难得出它适用的场景:

  1. 对于存储空间要求不高的场景(或者存储空间比较充裕)
  2. 需要进行较多的查询操作,而增加、修改、删除的操作次数相对较少的应用场景
    (这种“读多写少”的场景是比较常见的,很多的 web 程序(网站)都是如此)

🍌通过 SQL 操作索引

1. 查看索引
查看某个表是否有索引,以及有几个索引

show index from 表名;

这里有一个结论:MySQL 中的主键、unique 和外键都会自动生成索引

比如我们现在创建一个学生表,它有两列:id 和姓名,其中 id 是主键,姓名用 unique 约束。然后查看它的索引:

create table student(id int primary key,name varchar(20) unique);

查看索引
在这里插入图片描述

可以看到 id 和 name 都是这张表的索引

从上面的例子我们也可以看出,一个表可以有多个索引,而每个索引都是根据某个具体的列来展开的,这样,后续按照这个列来查询的时候,就能提高效率


2. 创建索引

除了主键、外键和 unique 作为索引,我们也可以自己创建索引:

create index 索引名 on 表名(列名);

举个例子,假设刚才创建的学生表没有设置主键和 unique,那么查看索引的结果集就为空
然后我们手动创建索引:

create index id_index on student(id);
create index name_index on student(name);

再次查看索引:

在这里插入图片描述

注意:创建索引也是一个比较危险的操作。如果表中没有数据或者数据比较少,此时创建索引没问题;但如果表中已经有很多数据,此时创建索引,就会触发大量的硬盘 IO,很可能就把数据库给搞挂了


3. 删除索引

drop index 索引名 on 表名
drop index id_index on student;
drop index name_index on student;

注意:删除索引也是一个危险操作


🍌底层数据结构

数据库的索引使用 B+ 树作为数据结构,其实 B+ 树就是针对数据库这个场景量身定制的
要理解 B+ 树,得先了解 B 树(B-树)

B 树是一个 N叉搜索树,是在二叉搜索树的基础上进行拓展,它一个节点上可能包含 N 个值,这 N 个值划分出(N + 1)个区间
举个例子,现在根节点有三个值,分别为30、40、50
那就会划分出4个区间,分别为:小于30的区间、30到40之间的区间、40到50之间的区间和大于50的区间,然后子节点又会继续划分出多个区间

在这里插入图片描述
从 B 树的特性可以看出,同样高度的树,它能表示的元素相比于二叉搜索树来说多了很多,所以使用 B 树来查询的时候,比较的次数比二叉搜索树多
比如上面的例子中,要找46的位置,就得先和30比较,比30大,那就得跟40比,比40大,就要跟50比,比50小,就说明46在40到50这个区间

当然这不意味着 B 树不如二叉搜索树,恰恰相反,因为同一个节点的 key 值都是一次硬盘 IO 就能读出来的。即使总的比较次数多了,但 B 树硬盘 IO 次数少了,而一次硬盘 IO 相当于内存中进行 1w 次比较,所以 B 树完全薄纱二叉搜索树

而 B+树则是在 B 树的基础上,又进行改进
同样是 N 叉搜索树,每个节点包含多个 key,不过 B+树只划分出 N 个区间,少了最右边的区间

还是举个例子

在这里插入图片描述
我们可以看到,B+树是没有大于15的区间的,这样就只有两个区间。对于小于8的区间,子节点中包含8;对于8到15的区间,子节点包含15。
也就是说每个节点的 key 会体现在子节点中,直到叶子节点。这样的话叶子节点就包含所有数据(数据全集),这样的好处在于查询过程中经过的硬盘 IO 次数是一样的(B树的硬盘 IO 有时多,有时少),查询时间是稳定

然后叶子节点之间用链式结构相连(图中红色箭头)
用链式节点的好处在于可以进行范围查询,比如现在要找出4到10这个区间,只需找出4,然后沿着链表往后遍历找到10就 ok 了

反之,如果没有链式结构,那就可能需要反复对树进行回溯,这样就很麻烦(比如找完4之后要回到上一层,然后去找10)

当然,因为现在是在讲数据库,所以关于B+树更详细的讨论,我们放到以后再讲


🍉事务

很多时候对数据库进行的多个操作,我们期望能够“打包”到一起,共同执行

先来看一个经典场景:转账
有一个账户表,记录用户 id、姓名和余额
在这里插入图片描述
假如现在张三向李四转账500,那就需要两条SQL语句:

update account set balance = balance - 500 where name = '张三';
update account set balance = balance + 500 where name = '李四';

但是有一个问题,就如果执行完第一个SQL之后,在执行第二个SQL前,数据库挂了,那等到数据库恢复的时候,就会发现张三钱少了,但是李四的钱没有多!

所以需要想个办法,使得即使数据库真挂了,也不会有这样的负面影响

事务就可以做到,它可以保证上述这两个SQL,要么都成功执行,要么都不执行
说是说“不执行”,但实际上还是执行了,只不过在数据库恢复的时候,把数据也还原回去了。这种还原的机制称为回滚机制事务的原子性本质上就是依托回滚
为什么能回滚呢?因为数据库通过日志(undo log 和 redo log)把之前的数据记录下来了,也就是写到文件里。即使数据库挂了,但是日志已经记录下来了,等到数据库重启之后,读取之前的日志,看看是否有那种执行了一半的事务,如果有,就会把这前面的操作进行回滚,恢复到没有操作之前的状态

🍌特性

谈到事务,我们就需要讲到它4个核心的特性:

  1. 原子性(最重要的特性)
    通过事务,把多个操作打包到一起
  2. 一致性
    相当于是原子性的延伸,就是当数据库中间出问题了,不会出现上述那种“钱凭空消失”这种异常情况;另一方面,通过约束来避免数据出现一些非法的情况
  3. 持久性
    对事务进行的任何修改,都是持久化存在的(因为是写入硬盘的),无论是重启程序,还是重启主机,修改都不会丢失(因为数据库本身就是为了持久化存储)
  4. 隔离性
    多个事务并发执行的时候,可能会带来一些问题,通过隔离性对这些问题进行权衡(就是看你是希望数据尽量准确,还是速度尽可能快)

前三个都比较好理解,我们主要来讲隔离性
先理解一个概念——“并发”
并发是计算机领域中一个很大的话题,后面所讲的“多线程”,其实就属于是“并发编程”中的一种典型实现方式

数据库是客户端——服务器结构的程序,一个服务器可能会涉及到多个客户端。那么,如果有多个客户端同时向数据库服务器发起事务请求,这个时候就叫作“并发执行事务”
如果这多个事务修改的是不同的表,那么问题不大;而如果是修改同一张表,就可能产生一些 bug

典型 bug 1:脏读问题
有两个事务1、2,其中事务1修改了某个数据,但此时事务还没有提交,而事务2读取了这个数据(事务2会多次读取这个数据),此时事务2读取到的数据,很可能是一个脏数据,因为事务1后续可能还要再次修改这个数据。
这就导致事务2第一次读取到的数据是A,但是第二次读取到的数据是B,前后不一致

解决脏读问题的核心思路就是降低事务的并发程度
要解决的话就得给写操作加锁,加锁意味着在释放锁之前,这个数据是无法访问的(写的时候不能读)


典型 bug 2:不可重复读
这个有点像脏读,但这是在写操作加锁的前提下导致的问题
还是以上面的脏读为例,此时来了一个事务3,它在事务2读数据的时候,修改了数据,这样也会导致事务2前后读取的数据不一致

要解决这个问题,就需要给读操作加锁,即读的时候不能写


典型 bug 3:幻读
现在有事务1、2,其中事务1修改数据,然后提交,事务2开始读数据。此时来了一个事务3,它新增了一些其他的数据,这就可能导致事务2两次读取的结果集(就是查询的时候,有多少行)不同

要解决幻读问题,就要串行化:不再进行任何并发,让每个事务都是串行执行的(执行完第一个,再执行第二个,再第三个…)

不过其实上述这三种情况,不算真正的 bug,主要还是得看实际的场景,要看你的场景是更关注数据的准确性,还是更关注效率


MySQL在配置中,提供了“隔离级别”的选项,我们可以根据需要,调整隔离级别,用来应对不同的情况

  1. read uncommitted:读未提交,此时并行程度最高,隔离程度最低,数据是最不靠谱的,可能出现脏读、不可重复读和幻读
  2. read committed:读已提交,相当于给写操作加锁。并行程度降低了,隔离程度提高了,效率会降低一些,此时可能会出现不可重复读和幻读
  3. repeatable read默认的隔离级别:可重复读,相当于给写操作和读操作加锁了。并行程度进一步降低,隔离程度进一步提高。此时仅可能出现幻读
  4. serializable:串行化,让所有事务都是串行执行。此时并行程度最低,隔离程度最高,效率最低,但是数据是最靠谱的

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

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

相关文章

Nginx的反向代理

Nginx的反向代理 location ^~ /aaa {proxy_pass http://192.168.15.78/; } 1. 跨域 2.Nginx 代理服务器缓存 3.Nginx 负载均衡 4. 动静分离 Nginx的跨域 跨源资源共享 (CORS) 是一种机制,它使用额外的 HTTP 标头让用户代理获得访问来自不同来域的服务器上选定资…

3.31学习总结

算法 解题思路 使用dfs,对蛋糕每层可能的高度和半径进行穷举.通过观察我们可以知道第一层的圆面积是它上面所有蛋糕层的圆面积之和,所以我们只要去求每层的侧面积就行了. 因为题目要求Ri > Ri1且Hi > Hi1,所以我们可以求出每层的最小体积和侧面积,用两个数组分别储存起来…

C语言实现猜数字游戏(有提示,限制次数版)

这次的猜数字游戏我添加了新的功能:为玩家添加了提示,以及输入数字的限制次数。 首先,我们的猜数字游戏需要一个菜单,来让玩家可以选择玩游戏还是退出游戏,所以我们需要开始就打印一个菜单: int main() {…

Mac air 个人免费版VMWare Fusion安装及配置教程

Mac air 安装免费版VMWare Fusion教程及问题解决 1、下载VMWare Fusion2、下载wins镜像文件3、开始配置4、出现的问题及解决方法4.1 如何跳过启动时的网络连接4.2 启动后,无法连接网络怎么办4.3 怎么实现将文件拖拽到虚拟机中 当你手上是一台Mac电脑,却需…

VS Code常用前端开发插件和基础配置

VS Code插件安装 VS Code提供了非常丰富的插件功能,根据你的需要,安装对应的插件可以大大提高开发效率。 完成前端开发,常见插件介绍: 1、Chinese (Simplified) Language Pack 适用于 VS Code 的中文(简体&#xff…

【原创】基于分位数回归的卷积长短期结合注意力机制的神经网络(CNN-QRLSTM-Attention)回归预测的MATLAB实现

基于分位数回归的卷积长短期结合注意力机制的神经网络(CNN-QRLSTM-Attention)是一种用于时间序列数据预测的深度学习模型。该模型结合了卷积神经网络(CNN)、长短期记忆网络(LSTM)和注意力机制(A…

C++ 数组 结构编程题

一 求100以内的所有素数 /* * 需要标记2~100 之间的数是否处理 * 用数组&#xff0c;初始为0 表示都是素数&#xff0c;如果 判断为合数则置为1过用 */ #include<stdio.h> #include<math.h> int main() {const int n 100;int isPrim[n 1] { 0 };int i, j;for (…

MAC的Safari浏览器没有声音解决办法

有一段时间没打开电脑&#xff0c;也不知道是系统自动更新或是什么缘故&#xff0c;所有浏览器都无法正常发声。 现象如下&#xff1a; 首先&#xff0c;Safari浏览器无法自动播放声音&#xff0c;下载的360浏览器现象一致&#xff0c;但是播放其他音乐播放软件和视频软件都正…

JavaScript(二)---【js数组、js对象、this指针】

零.前言 JavaScript(一)---【js的两种导入方式、全局作用域、函数作用域、块作用域】-CSDN博客 一.js数组 在js中也有数组的概念&#xff0c;数组使用“[]”定义&#xff0c;其中数组中还可以嵌套数组从而达到多层数组的作用。 访问数组中的某个元素&#xff0c;我们可以直…

pymysql使用记录

最近由于需要来学习一下pymysql。 先来认识一下pymysql&#xff1a; PyMySQL 是 Python 中一个用于连接 MySQL 数据库的库。它允许 Python 程序通过简单的 API 调用来连接、操作和管理 MySQL 数据库。PyMySQL 是在 Python 中使用纯 Python 编写的&#xff0c;因此它可以在几…

MySQL编程实战LeetCode经典考题

文章简介 本文主要收集了LeetCode上关于MySQL的一些经典考题。 后续也会陆续把所有经典考题补充完整。 175.组合两个表 175.组合两个表 解答&#xff1a; select p.FirstName as firstName, p.LastName as lastName,a.City as city, a.State as state from Person p l…

loadbalancer 引入与使用

在消费中pom中引入 <dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-loadbalancer</artifactId> </dependency> 请求调用加 LoadBalanced 注解 进行服务调用 默认负载均衡是轮训模式 想要切换…

【b站李炎恢】Vue.js Element UI 下 | 十天技能课堂 | 更新中... | 李炎恢

课程地址&#xff1a;【Vue.js Element UI | 十天技能课堂 | 更新中... | 李炎恢】 https://www.bilibili.com/video/BV1U54y127GB/?share_sourcecopy_web&vd_sourceb1cb921b73fe3808550eaf2224d1c155 备注&#xff1a;虽然标题声明还在更新中&#xff0c;但是看一些常用…

Python库使用介绍 LivermorE AI Projector for Computed Tomography LEAP

Python库使用介绍 LivermorE AI Projector for Computed Tomography LEAP 前言Projector 用于设定投影参数的类参数解释&#xff1a;其它功能load_param(str filepath)forward(ipt, project_mode"forward") 样例代码后记 前言 github开源代码 python API文档 作为一…

TypeScript-自动编译

1.生成文件 tsc --init 2.修改配置文件 说明&#xff1a;通过CTRLF搜索到以下单词&#xff0c;进行修改。 "strict": true, //是否开启严格模式 "outDir": "./outFile", //表示ts文件最终编译为js文件&#xff0c;js文件存放的位置 3.新…

C++心决之命名空间、重载函数和引用

目录 1. C关键字(C98) 2. 命名空间 2.1 命名空间定义 2.2 命名空间使用 3. C输入&输出 4. 缺省参数 4.1 缺省参数概念 4.2 缺省参数分类 5. 函数重载 5.1 函数重载概念 5.2 C支持函数重载的原理--名字修饰(name Mangling) 6. 引用 6.1 引用概念 6.2 引用特性…

基于spark的大数据分析预测地震受灾情况的系统设计

基于spark的大数据分析预测地震受灾情况的系统设计 在本篇博客中,我们将介绍如何使用Apache Spark框架进行地震受灾情况的预测。我们将结合数据分析、特征工程、模型训练和评估等步骤,最终建立一个预测模型来预测地震造成的破坏程度,同时使用可视化大屏的方式展示数据的分布…

DreamSim技术小结

paperhttps://arxiv.org/abs/2306.09344codehttps://github.com/ssundaram21/dreamsimorgMiT个人博客主页http://myhz0606.com/article/dream_sim 1 Motivation 目前较为成熟度量图片相似性的做法是通过模型将图片转为embedding&#xff0c;再用余弦相似度来度量相似性。虽然…

【数据分析面试】1. 计算年度收入百分比(SQL)

题目 你需要为公司的营收来源生成一份年度报告。计算截止目前为止&#xff0c;在表格中记录的第一年和最后一年所创造的总收入百分比。将百分比四舍五入到两位小数。 示例&#xff1a; 输入&#xff1a; annual_payments 表 列名类型amountINTEGERcreated_atDATETIMEstatusV…

Linux企业级别日志的查找

企业级别日志的查找 查看mysql数据库的日志错误日志&#xff08;Error Log&#xff09;查询日志&#xff08;General Query Log&#xff09;慢查询日志&#xff08;Slow Query Log&#xff09;事务日志&#xff08;Transaction Log&#xff09;二进制日志&#xff08;Binary Lo…