【MySQL】事务和索引

本文涉及的产品
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
云数据库 RDS MySQL,集群系列 2核4GB
推荐场景:
搭建个人博客
云数据库 RDS MySQL,高可用系列 2核4GB
简介: 事务(Transaction)1. 定义2. 如何操作事务2.1 SQL 语句操作事务的几个关键字2.2 使用 SQL 语句操作事务2.3 JDBC 操作事务3. 事务的四个特性:ACID3.1 Atomic(原子性)3.1.1 理解原子性3.2 Consistency(一致性)3.2.1 以银行转账的例子理解一致性3.3 Isolation(隔离性)3.4 Durability(持久性)4. 隔离级别4.1 读未提交4.2 读已提交4.3 可重复读4.4 快照读4.5 可串行化索引1. 索引的分类2. 索引的作用3. 创建索引4. 索引的基本原理

事务(Transaction)

1. 定义

  • 事务这个词的含义很广泛,并不一定特指数据库中的事务
  • 在开发者看来,一个不可再分的业务动作就是一个事务,这个动作最终表达为一条或者多条 SQL 语句


2. 如何操作事务

2.1 SQL 语句操作事务的几个关键字

==start transaction:==开启事务

==rollback:==回滚,主动让事务失败

==commit:==提交事务,代表事务完成,对事物的所有操作在 commit 之后才会生效


2.2 使用 SQL 语句操作事务

在 start transaction 和 commit(或 rollback)之间写出此事务的 SQL 语句


start transaction;
-- SQL1
-- SQL2
commit;   -- 事务正常提交
-- rollback;  -- 我们主动让事务失败

2.3 JDBC 操作事务

在使用 JDBC 时,Connection 下有一个 autocommit 属性,会使事务自动提交,默认情况下,此属性值是 true。


开启状态下,意味着每一条 SQL 都被视为一个独立的事务。我们要想让多条 SQL 在同一个事务中,只需使用 setAutoCommit 方法修改此属性为 false即可。


修改之后不会自动提交,就需要用到 Connection 下的两个方法 —— commit 和 rollback 来手动提交和主动失败。

String sql1 = "";
String sql2 = "";
// 要使用事务,在同一个事务中,操作 sql1 和 sql2,意味着必须在一条 Connection 完成
try (Connection c = DBUtil.connection()) {
    c.setAutoCommit(false);
    try (PreparedStatement ps = c.prepareStatement(sql1)) {
        ps.executeUpdate();
    }
    try (PreparedStatement ps = c.prepareStatement(sql2)) {
        ps.executeUpdate();
    }
    c.commit();


3. 事务的四个特性:ACID

事务的四大特性中,一致性是最基本的,其他三个特性都是为了维护一致性而生的

3.1 Atomic(原子性)

业务动作对应的 SQL 应该是看作一个整体,不可再分的。


3.1.1 理解原子性

简单来说,就是一个事务中的所有 SQL 要么全部成功,要么全部失败,所有的事务处于一种同生共死的状态。


体现在代码中就是,事务中有两条 SQL ,SQL1 执行通过,但是在执行 SQL2 时出现异常,此时事务就会回滚,两条 SQL 执行结果都被判定为失败。只有两条 SQL 都执行通过,事务才会提交


3.2 Consistency(一致性)

一致性由开发者来保证,针对数据整体做的不可变的承诺。


3.2.1 以银行转账的例子理解一致性

我们去银行从 ATM 中转账的时候一般分为两个步骤:


我的银行卡余额减少

转账接收方余额增加

如果在第一步完成之后,银行的服务器突然宕机,我的余额减少了,但是转账接收方的余额没有增加,我就会白白损失一笔巨款。在数据库中,这就是所谓的 不一致性


当一致性被维护时,银行的服务器突然宕机,转账这个业务应立即被判断为失败,我的余额也不会减少


3.3 Isolation(隔离性)

当有多个事务同时操作一段数据时,互相之间不会彼此干扰。


以上这句对隔离性的定义其实是比较理想的。事实上,如果要追求真正的隔离性,就要以牺牲并发性为代价的,所以 SQL 标准制定了隔离级别


3.4 Durability(持久性)

持续性也称为永久性,指一个事务一旦提交,它对数据库中数据的改变是永久性的。


4. 隔离级别

SQL 中的隔离级别分为以下几种:


serializable(可串行性)

snapshot read(快照读)

repeatable read(可重复读)

read committed(读已提交)

read uncommited(读未提交)

如下图所示,越往左隔离性越好,越往右并发性越好(性能更高)


26.png


4.1 读未提交

多个同时执行的事务,可以读取到其他事务处于未提交时的数据修改,可以认为完全没有隔离性,在此隔离级别下会产生副作用——脏读不可重复读幻读

脏读:读取到了脏数据,读到了其他事务没有提交的数据修改,而这段数据随时很有可能会被回滚,这样就会破坏一致性

27.png


4.2 读已提交

读已提交就是可以读取到其他事务已经提交的数据修改。

“ 读已提交 ” 隔离级别中避免了脏读,但是不可避免 不可重复读幻读

不可重复读:同一个事务中,可能出现多次读取同一份数据,但结果不同。


28.png


4.3 可重复读

保证了在一次事务中(没有提交或者回滚),读取到的同一块数据无论何时的值都一样,即使有别的事务对这块数据进行了修改,也不会有影响

传统意义上的可重复读避免了脏读和不可重复读,但是仍然避免不了幻读


29.png


幻读:本事务修改了表中的数据,但是在本事务提交之前表中被另一个事务插入了一条数据并且提交了,这样就会导致本数据会看到一条突然出现的 “ 幽灵般的 ” 数据

出现幻读的原因是:可重复读只针对表中已有的数据做保护,对新添加的数据不做保护


30.png


4.4 快照读

快照读其实不是标准中存在的隔离级别,快照读连幻读的副作用都没有,目前来说基本没有副作用


MySQL 中的 “ 可重复读 ” 可以看作实际上的 “ 快照读 ”,MySQL 默认情况下的隔离级别就是可重复读


4.5 可串行化

微观视角下,每个事务必须排好队,一次只执行一条事务,每条事务之间完全隔离;宏观视角下,让然看作 “ 同时进行 ”,但是并发性(性能)差


索引

1. 索引的分类

index:普通索引


unique:唯一索引


fulltext:全文索引


spatial:时空索引


primary:主键


以下全文只针对普通索引


2. 索引的作用

索引的作用是用来提高查询速度


一般来说,在表中查询某条数据时,会把所有的元素遍历一遍,找到符合条件的元素,对表中的某个字段添加索引之后,就像是对这个字段创建了目录,可以大大提高查询速度


3. 创建索引

-- 使用 ALTER  TABLE 语句添加索引
ALTER  TABLE  `table_name`  ADD  PRIMARY  KEY (  `column`  ) 
-- 使用 create 语句添加索引
CREATE INDEX `index_name` on `table_name` (`column_name`)

4. 索引的基本原理

索引的背后可以看作是一颗搜索树,搜索树的 key 是添加过索引的字段,value 可以看作是对应数据在硬盘上的位置(一种可能)


4.1 添加索引之后的查询过程

第一步,从搜索树(索引)中,根据添加索引的字段名找到匹配数据的位置

第二步,直接根据位置读取数据

相比未添加索引的遍历全表查询,速度会大幅提升


5. 索引的 hit 和 miss

注意,索引只会应用在被添加的字段,其他字段不受影响


一张表中,命中索引被称为 hit,有索引但未命中被称为 miss


6. 索引的优缺点

优点:


提升查询速度

缺点:


造成空间的使用增加

造成修改的性能下降(删、改、增)

添加完索引之后,还得保存索引数据,所以空间的使用就会增加;没有索引时修改数据只需要修改原始数据即可,有了索引之后,除了修改原始数据之外,还得修改索引结构,所以性能会下降


7. 索引的使用场景

数据量达到一定规模

针对查询很多、修改较少的表考虑索引

只针对频繁被查询的字段建立索引


8. 了解 explain 命令

通过 explain 命令可以判断是否命中索引,将 explain 命令加载 select 命令前即可


使用 explain 命令之后会出现如下图字段,比较 rows 字段即可判断是否添加索引,rows 字段是此 select 扫描的行数,一般来说,添加过索引后扫描的行数会非常少(前提数据庞大)


31.png


相关实践学习
如何在云端创建MySQL数据库
开始实验后,系统会自动创建一台自建MySQL的 源数据库 ECS 实例和一台 目标数据库 RDS。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助     相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
目录
相关文章
|
25天前
|
存储 关系型数据库 MySQL
阿里面试:为什么要索引?什么是MySQL索引?底层结构是什么?
尼恩是一位资深架构师,他在自己的读者交流群中分享了关于MySQL索引的重要知识点。索引是帮助MySQL高效获取数据的数据结构,主要作用包括显著提升查询速度、降低磁盘I/O次数、优化排序与分组操作以及提升复杂查询的性能。MySQL支持多种索引类型,如主键索引、唯一索引、普通索引、全文索引和空间数据索引。索引的底层数据结构主要是B+树,它能够有效支持范围查询和顺序遍历,同时保持高效的插入、删除和查找性能。尼恩还强调了索引的优缺点,并提供了多个面试题及其解答,帮助读者在面试中脱颖而出。相关资料可在公众号【技术自由圈】获取。
|
25天前
|
存储 SQL 关系型数据库
MySQL的事务隔离级别
【10月更文挑战第17天】MySQL的事务隔离级别
96 43
|
1月前
|
存储 关系型数据库 MySQL
Mysql(4)—数据库索引
数据库索引是用于提高数据检索效率的数据结构,类似于书籍中的索引。它允许用户快速找到数据,而无需扫描整个表。MySQL中的索引可以显著提升查询速度,使数据库操作更加高效。索引的发展经历了从无索引、简单索引到B-树、哈希索引、位图索引、全文索引等多个阶段。
61 3
Mysql(4)—数据库索引
|
16天前
|
监控 关系型数据库 MySQL
数据库优化:MySQL索引策略与查询性能调优实战
【10月更文挑战第27天】本文深入探讨了MySQL的索引策略和查询性能调优技巧。通过介绍B-Tree索引、哈希索引和全文索引等不同类型,以及如何创建和维护索引,结合实战案例分析查询执行计划,帮助读者掌握提升查询性能的方法。定期优化索引和调整查询语句是提高数据库性能的关键。
82 1
|
26天前
|
存储 关系型数据库 MySQL
如何在MySQL中进行索引的创建和管理?
【10月更文挑战第16天】如何在MySQL中进行索引的创建和管理?
55 1
|
1月前
|
SQL 关系型数据库 MySQL
阿里面试:MYSQL 事务ACID,底层原理是什么? 具体是如何实现的?
尼恩,一位40岁的资深架构师,通过其丰富的经验和深厚的技術功底,为众多读者提供了宝贵的面试指导和技术分享。在他的读者交流群中,许多小伙伴获得了来自一线互联网企业的面试机会,并成功应对了诸如事务ACID特性实现、MVCC等相关面试题。尼恩特别整理了这些常见面试题的系统化解答,形成了《MVCC 学习圣经:一次穿透MYSQL MVCC》PDF文档,旨在帮助大家在面试中展示出扎实的技术功底,提高面试成功率。此外,他还编写了《尼恩Java面试宝典》等资料,涵盖了大量面试题和答案,帮助读者全面提升技术面试的表现。这些资料不仅内容详实,而且持续更新,是求职者备战技术面试的宝贵资源。
阿里面试:MYSQL 事务ACID,底层原理是什么? 具体是如何实现的?
|
16天前
|
监控 关系型数据库 MySQL
数据库优化:MySQL索引策略与查询性能调优实战
【10月更文挑战第26天】数据库作为现代应用系统的核心组件,其性能优化至关重要。本文主要探讨MySQL的索引策略与查询性能调优。通过合理创建索引(如B-Tree、复合索引)和优化查询语句(如使用EXPLAIN、优化分页查询),可以显著提升数据库的响应速度和稳定性。实践中还需定期审查慢查询日志,持续优化性能。
47 0
|
28天前
|
监控 关系型数据库 MySQL
mysql8索引优化
综上所述,深入理解和有效实施这些索引优化策略,是解锁MySQL 8.0数据库高性能查询的关键。
28 0
|
1月前
|
SQL 关系型数据库 MySQL
美团面试:mysql 索引失效?怎么解决? (重点知识,建议收藏,读10遍+)
本文详细解析了MySQL索引失效的多种场景及解决方法,包括破坏最左匹配原则、索引覆盖原则、前缀匹配原则、`ORDER BY`排序不当、`OR`关键字使用不当、索引列上有计算或函数、使用`NOT IN`和`NOT EXISTS`不当、列的比对等。通过实例演示和`EXPLAIN`命令分析,帮助读者深入理解索引失效的原因,并提供相应的优化建议。文章还推荐了《尼恩Java面试宝典》等资源,助力面试者提升技术水平,顺利通过面试。
|
1月前
|
关系型数据库 MySQL 数据库
深入浅出MySQL索引优化:提升数据库性能的关键
在这个数据驱动的时代,数据库性能的优劣直接关系到应用的响应速度和用户体验。MySQL作为广泛使用的数据库之一,其索引优化是提升查询性能的关键。本文将带你一探MySQL索引的内部机制,分析索引的类型及其适用场景,并通过实际案例演示如何诊断和优化索引,以实现数据库性能的飞跃。