MySQL之索引与事务

news/2024/11/26 15:06:49/

索引

索引的分类

从定义的分类来看,索引分为:

主键索引:必须唯一且不能有null值

唯一索引:必须唯一,但是允许有null值

普通索引:即对一个列添加索引,也称单列索引

联合索引:对多个列合并添加索引,也称多列索引

索引的底层数据结构

索引是一种数据结构,可以用来快速查找和排序数据,MySQL的innerDB引擎,用的是B+数据结构来存储索引,特点是非叶子节点值存储索引值和指针,叶子节点用双向链表的形式存储数据。使用黑马于洪波老师的图:

 B+树是从搜索二叉树->红黑树->B树,进化来的。它的好处有:

  1. 节点采用多阶的方式,相对二叉树、红黑树,树更矮,查询效率更高

  2. 叶子节点才存储数据且采用双向链表的方式,相对B树,范围查询的效率更高

聚簇索引和非聚簇索引

从MySQL将索引存储的物理形式来看,可以分为聚簇索引和非聚簇索引(也叫二级索引),这2个都是B+树,区别如下:

  1. 聚簇索引:叶子节点保存的是整行数据。只能由一个聚簇索引。通常是主键(没有主键则使用唯一索引或MySQL隐藏的rowid列)

  2. 非聚簇索引:叶子节点保存的是主键值。除了聚簇索引外,其他的索引都是以非聚簇索引的形式保存的

 为什么要了解聚簇索引和非聚簇索引呢?因为这里涉及到MySQL查询非常重要的一个概念:回表

 回表查询

假设现在有一张表tableA,表里面有3个字段列,id主键,name建立了普通索引,age年龄就是一个普通列

-- 创建表A,id为主键,默认用的是innoDB引擎
create table `tableA`(id int primary key,name varchar(200),age int
);
-- 给name添加普通索引
create index name_index on tableA(name);

此时MySQL底层会存储2个索引结构,一个是以ID为主键的聚簇索引,一个是以name为普通索引的非聚簇索引。

先看会触发回表查询的情况:

select id,name,age from tableA where name = '张三';

查询条件name = '张三',那么走的是name的非聚簇索引;select要返回的字段有3个:id,name,age;当非聚簇索引定位到'张三'这个数据的时候,只能获取到id,name这2个字段数据(因为非聚簇索引只存储了主键值)。age这个列是拿不到的,必须根据拿到的id值,再去聚簇索引中定位到这条数据,然后获取age字段值返回;这个根据id重新去聚簇索引中查找数据,就叫回表查询。在大数据量的情况下,回表是比较影响性能的。

在看一个不触发回表的SQL。

-- 不会触发回表,因为通过name索引,可以直接到要返回的id,name字段
select id,name from tableA where name = '张三';

上面的sql是不会触发回表的,查询条件name = '张三',走的是name的非聚簇索引,因为select id,name;表示查询要返回的列为id和name,通过非聚簇索引定位到'张三'这条数据时,非聚簇索引叶子节点保存了主键值id,那么要查询的列都齐了,可以直接返回,就不需要回表。 

索引失效的情况

以下情况下索引会失效:

 

-- 1. 对索引列name做运算导致索引失效
select * from table where upper(name) = 'ABC';-- 2. 类型转换,这里name是varchar类型,但是却跟123数值类型做比较,虽然MySQL执行这种,但是会导致索引失效
select * from table where name = 123;
-- 正确的方法,'123'
select * from table where name = '123';-- 3. 使用模糊查询,且开头为%
select * from table where name = '%123';
-- 正确的方法,开头不能为%
select * from table where name = '123%';-- 4. 聚合索引,没有满足最左前缀法制,也就是最左表的索引列要出现
-- 假设有一个聚合索引name,age
-- 失效的写法 age放在了name的前面,不满足最左前缀法制
select * from table where age = 18 and name = '123';
-- 正确的写法,按聚合索引顺序编写
select * from table where name = '123' and age = 18;

事务

事务的特性

事务的特性可以总结为ACID原则:

原子性(Atomicity):事务里的操作,要么全部执行成功,要么全部执行失败

一致性(Consistency):事务操作前后,数据的状态保存一致

隔离性(Isolation):事务需在不受外部并发的环境下运行

持久性(Durability):事务一旦提交,那么对数据的修改就是永久性的

undo log日志,保证原子性和一致性,redo log日志保证持久性,MySQL事务隔离级别保证隔离性。

undo log日志

逻辑日志,当insert新增一条数据时,会对应记录一条delete的恢复语句,update修改一条数据时,会记录一条update相反的恢复语句。

一旦发生错误需要事务回滚,那么执行undo log日志里的内容恢复数据即可。

redo log日志

物理日志,对数据库的修改,会先持久化到redo log日志里,也就是Write-Ahead Logging日志优先的思想,当事务提交后发生服务器宕机时,恢复redo log日志里的内容即可。

事务的隔离级别

在高并发的时候,怎么保证事务的隔离性呢。先看下并发事务会带来的一些问题:

脏读:一个事务读到了另一个事务还没有提交的数据

不可重复读:一个事务两次读取同一条数据,得到的结果不一样

幻读:一个事务读取不到此条数据,但是在insert这条数据时,却提示此条数据已存在,像是出现了幻影

MySQL中有4种隔离级别,对应解决上面3种问题:

隔离级别

脏读

不可重复读

幻读

读未提交 READ UNCOMMITTED 简称RU

不解决

不解决

不解决

读已提交 READ COMMITTED 简称RC

解决

不解决不解决

可重复读 REPEATABLE READ 简称RR

解决解决

串行化 SERIALIZABLE

解决解决解决

大多数数据库如Oracle、sqlServer默认级别都是RC读已提交。MySQL默认的隔离级别是RR可重复读。 


http://www.ppmy.cn/news/1550090.html

相关文章

企业办公自动化:Spring Boot OA管理系统开发与实践

2相关技术 2.1 MYSQL数据库 MySQL是一个真正的多用户、多线程SQL数据库服务器。 是基于SQL的客户/服务器模式的关系数据库管理系统,它的有点有有功能强大、使用简单、管理方便、安全可靠性高、运行速度快、多线程、跨平台性、完全网络化、稳定性等,非常…

从零开始打造个人博客:我的网页设计之旅

✅作者简介:2022年博客新星 第八。热爱国学的Java后端开发者,修心和技术同步精进。 🍎个人主页:Java Fans的博客 🍊个人信条:不迁怒,不贰过。小知识,大智慧。 ✨特色专栏&#xff1a…

算法日记 33 day 动态规划(打家劫舍,股票买卖)

今天来看看动态规划的打家劫舍和买卖股票的问题。 上题目!!!! 题目:打家劫舍 198. 打家劫舍 - 力扣(LeetCode) 你是一个专业的小偷,计划偷窃沿街的房屋。每间房内都藏有一定的现金…

Flink Standalone 集群模式安装部署教程

目录 一、前言 二、环境准备 三、安装步骤 1. 下载并安装 Flink 4. 配置 Flink 5. 配置环境变量 6. 启动 Flink 集群 7. 访问 Flink Web 界面 四、简单测试 五、常见问题和解决办法 1. 启动失败,无法连接到 TaskManager 2. Web 界面无法访问 六、总结 …

八股文-基础知识-面试题汇总(一)

面向对象和面向过程的区别? 面向对象和面向过程是两种不同的编程范式,它们在设计和实现软件时有着不同的理念和方法。面向对象更适合大型、复杂的项目,尤其是需要维护和扩展的系统;而面向过程更适合小型、线性的任务或对性能要求…

Hadoop 系列 MapReduce:Map、Shuffle、Reduce

文章目录 前言MapReduce 基本流程概述MapReduce 三个核心阶段详解Map 阶段工作原理 Shuffle 阶段具体步骤分区(Partition)排序(Sort)分组(Combine 和 Grouping) Reduce 阶段工作原理 MapReduce 应用场景Map…

[M最短路] lc743. 网络延迟时间(spfa最短路+单源最短路)

文章目录 1. 题目来源2. 题目解析 1. 题目来源 链接:743. 网络延迟时间 相关链接: [图最短路模板] 五大最短路常用模板) 2. 题目解析 怎么讲呢,挺抽象的…很久没写最短路算法了。反正也是写出来了,但脱离了模板,把…

微信小程序下拉刷新与上拉触底的全面教程

微信小程序下拉刷新与上拉触底的全面教程 引言 在微信小程序的开发中,用户体验至关重要。下拉刷新和上拉触底是提高用户交互体验的重要功能,能够让用户轻松获取最新数据和内容。本文将详细介绍这两个功能的实现方式,结合实际案例、代码示例和图片展示,帮助开发者轻松掌握…