「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:串行化,让所有事务都是串行执行。此时并行程度最低,隔离程度最高,效率最低,但是数据是最靠谱的

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

网络编程的学习1

网络编程 在网络通信协议下,不同计算机上运行的程序,进行数据传输。 三要素 ip:设备在网络中的地址,是唯一的标识。 ipv4:采取32位地址长度,分成4组。 ipv6:采用128位地址长度,分成8组。 …

安卓SharedPreferences使用

目录 一、简介二、使用2.1 getSharedPreferences2.2 增加数据2.3 读取数据2.4 删除数据2.5 修改数据2.6 清除数据2.7 提交数据 一、简介 SharedPreferences是Android平台上一个轻量级的存储类,主要是保存一些常用的配置比如窗口状态,一般在Activity、重…

12.Python文件读写

文件是数据的载体,程序可以从文件中读取数据,也可以将数据写 入文件中,本章重点介绍如何在Python中进行文件读写。 1 打开文件 我们在使用文件之前要先将文件打开,这通过open()函数实现。 open&#xff0…

JJJ:linux系统中第一个进程

以linux4.19内核linux系统中第一个进程。 执行shell指令 ps -ef 结果如下: xxxxxx-virtual-machine:~$ ps -ef UID PID PPID C STIME TTY TIME CMD root 1 0 0 20:55 ? 00:00:02 /sbin/init splash root …

【Web应用技术基础】CSS(4)——背景样式

第1题&#xff1a;背景颜色 .html <!DOCTYPE html> <html><head><meta charset"utf-8"><title>Hello World</title><link rel"stylesheet" href"step1/CSS/style.css"> </head><body>&…

词令蚂蚁庄园今日答案正确答案怎么获取查看蚂蚁庄园今天问题的正确答案?

词令蚂蚁庄园今日答案正确答案怎么获取查看蚂蚁庄园今天问题的正确答案&#xff1f; 1、打开「词令」关键词口令直达工具&#xff1b; 2、输入词令关键词直达口令「今日答案999」&#xff1b; 3、搜索直达词令蚂蚁庄园今日问题的正确答案&#xff1b; *注&#xff1a;词令蚂蚁…

【PythonGIS】Python实现批量导出面矢量要素(单个多面矢量->多个单面矢量)

可怜的我周六还在工作&#xff0c;已经很久没更新过博客了&#xff0c;今天正好有空就和大家分享一下。今天给大家带来的是使用Python将包含多个面要素/线要素的矢量批量导出单个要素的矢量&#xff0c;即一个要素一个矢量文件。之前写过多个矢量文件合并成一个矢量文件的博文&…

西南交大swjtu算法实验3.3|穷举法

1.实验目的 通过具体例子学习排列这种典型的穷举算法的求解过程以及程序框架&#xff0c;分析其算法的求解过程&#xff0c;以及如何设计穷举法解决实际问题。通过本实验&#xff0c;理解穷举法的特点以及实际应用中的局限性。 2.实验任务 有n (n>1&#xff09;个任务需要…

Visual Studio 2022 中VLD库如何安装

GitHub链接 Release v2.5.1 KindDragon/vld 点击可执行程序进行下载 点击可执行程序进行安装 双击打开 一直点击next即可完成安装&#xff08;不用在意安装路径&#xff0c;总共不到2MB&#xff09; 如果GitHub无法打开&#xff0c;可以私信我发你安装包直接安装

fpga_awb

色温: sesor原始图像中的白色如果不经AWB处理&#xff0c;在高色温(如阴天)下偏蓝&#xff0c;在低色温下偏黄。 引入白平衡算法 而AWB的核心就是调整图像色温&#xff0c;使得摄像头采集的图像更加真实&#xff0c;达到人眼观察的效果。 白平衡一般通过调节传感器输出图像RGB…

【aws】架构图工具推荐

碎碎念 以前以为日本冰箱论是个梗&#xff0c;结果居然是真的。用光盘传真其实还能理解&#xff08;毕竟我也喜欢电子古董2333&#xff09;&#xff0c;但是画架构图居然用的是excel&#xff0b;截图&#xff01;啊苍天呐&#xff0c;然后看到隔壁工位用excel画web原型又感觉释…

svg实现环形进度条

实现效果图&#xff1a; svg相关知识 这里只介绍本次用到的元素&#xff0c;更多详情&#xff1a;SVG&#xff1a;可缩放矢量图形 defs&#xff1a;定义需要重复利用的图形元素linearGradient&#xff1a;定义线性渐变&#xff0c;用来图形元素的填充或描边使用stop&#x…

hcip综合实验2

目录 实验拓扑&#xff1a; 实验要求&#xff1a; 实验思路&#xff1a; 实验步骤&#xff1a; 1.配置设备接口IP 2.通过配置缺省路由让公网互通 3.配置ppp 1.R1和R5间的ppp的PAP认证&#xff1b; 2.R2与R5之间的ppp的CHAP认证; 3. R3与R5之间的HDLC封装; 4.构建R1、…

动态规划之子序列(三)

583. 两个字符串的删除操作 给定两个单词 word1 和 word2&#xff0c;找到使得 word1 和 word2 相同所需的最小步数&#xff0c;每步可以删除任意一个字符串中的一个字符。 示例&#xff1a; 输入: “sea”, “eat” 输出: 2 解释: 第一步将"sea"变为"ea"…

c实现猜数游戏(猜不对可是要自动帮你电脑关机)

接下来的日子会顺顺利利&#xff0c;万事胜意&#xff0c;生活明朗-----------林辞忧 前言 猜数字游戏作为一个基础的C程序小项目&#xff0c;实现简单&#xff0c;可以帮助我们巩固很多知识&#xff0c;作为扩展接下来我们实现一个自定猜数次数&#xff0c;用完次数电脑自动…

keepalived+LVS高可用部署

目录 一.两台设备&#xff08;2.130和2.133&#xff09;作为调度器&#xff0c;前主后备 1.部署keepalived 2.修改配置文件准备启动 3.配置keepalived的系统日志并启动 二.模拟调度器掉点和web服务进程丢失 1.调度器掉点 2.当类似于httpd这种网站服务掉点 三.以三种健康…

【从前端入门到全栈】前端框架之核心概念

大家好&#xff0c;我是江辰&#xff0c;从前端入门到全栈是我全新系列文章&#xff0c;从去年一直囔囔着要写&#xff0c;今年总算开始了&#xff01;预计在10篇左右。知识面从 前端&#xff0c;后端&#xff0c;运维&#xff0c;脚本等&#xff0c;都有涉及&#xff0c;主打一…

Spark-Scala语言实战(9)

之前的文章中&#xff0c;我们学习了如何在spark中使用RDD方法的flatMap,take,union。想了解的朋友可以查看这篇文章。同时&#xff0c;希望我的文章能帮助到你&#xff0c;如果觉得我的文章写的不错&#xff0c;请留下你宝贵的点赞&#xff0c;谢谢。 Spark-Scala语言实战&am…

数据分析web可视化神器---streamlit框架,无需懂前端也能搭建出精美的web网站页面

✨✨ 欢迎大家来到景天科技苑✨✨ &#x1f388;&#x1f388; 养成好习惯&#xff0c;先赞后看哦~&#x1f388;&#x1f388; 所属的专栏&#xff1a;数据分析系统化教学&#xff0c;零基础到进阶实战 景天的主页&#xff1a;景天科技苑 文章目录 Streamlit什么是streamli…

基于springboot+vue实现的学校田径运动会管理系统

作者主页&#xff1a;Java码库 主营内容&#xff1a;SpringBoot、Vue、SSM、HLMT、Jsp、PHP、Nodejs、Python、爬虫、数据可视化、小程序、安卓app等设计与开发。 收藏点赞不迷路 关注作者有好处 文末获取源码 技术选型 【后端】&#xff1a;Java 【框架】&#xff1a;spring…