索引和事务究竟是何方神圣?那可是面试中的常客!

本文涉及的产品
日志服务 SLS,月写入数据量 50GB 1个月
简介: 索引和事务究竟是何方神圣?那可是面试中的常客!

在本文中,介绍的是MySQL中的索引和事务。但是,在关系型数据库中,这些知识也都通用



索引

1.介绍索引

1.1.什么是索引

(1)索引是一种特殊的文件,包含着对数据表里所有记录的引用指针。可以对表中的一列或多列创建索引,并指定索引的类型,各类索引有各自的数据结构实现

(2)索引就是一种类似于目录的东西。表相当于一本图,而索引就相当于书的目录,表中的内容就相当于书中的内容

1.2.索引的优点

可以提高查询速度

1.3.索引的缺点

(1)索引会占据额外的存储空间,一般都是在硬盘上面

(2)索引可能会拖慢增删改的速度

1.4.索引的使用场景

推荐:

(1)数据量比较大,而且常使用条件查询

(2)数据库的插入和修改操作使用频率比较低

(3)索引会占用额外的磁盘空间

不推荐:

(1)非条件查询

(2)经常做插入、修改操作

(3)磁盘空间不足

2.索引的基本操作

2.1.查看索引

(1)语法:show index from 表名;

(2)示例:

(3)哪些操作会自带索引

1)主键列

2)带unique的

3)foreign key(外键)

2.2.创造索引

(1)语法:create index 索引名字 on 表名(列名);

(2)索引是创建在列上面的。在查询的时候,也需要查询有索引的一列,才能达到提速的效果

(3)示例

查看刚才创造的索引:

(4)创造索引的注意事项

在数据量很大的时候,是不建议再加上索引的,否则会引发大量的CPU/硬盘IO的消耗;所以,一般在建表初期就考虑是否要加上索引    

(5)做法

1)另外搞个机器,也搭建好一样的数据库服务器

2)创建表,建立索引(此时是空表)

3)把旧的数据库的数据,导入到新的数据库中(非常耗时,但也要控制好速度,否则容易挂)

4)数据导好了,把应用程序的请求切换到新的服务器上

2.3.删除索引

(1)语法:drop index 索引名 on 表名;

(2)示例:

3.索引的底层原理

在这里面会将关于索引背后的数据结构是什么?有什么优势?在查询的时候,是如何工作的?

在innodb存储引擎下,数据库索引底层的数据结构一般是B+树,表不存在任何主键、外键和unique等,索引的背后就不再是B+树。

3.1.简单介绍B+树

(1)是一棵N叉搜索树,每个结点可以有多个值

(2)非叶子结点的值最终都会出现在其叶子结点上

(3)最终的叶子结点(最底层)就是数据的全集

(4)B+树的大致样子:

(5)特点

每个结点中的值都会在下一层中出现,最终就会形成最后一层叶子结点就是数据的全集

3.2.B+树相比B树的优势

(1)非常方便进行遍历和范围查询

(2)任何一次查询操作,最终都要落到叶子结点完成的,所有的查询操作经历的硬盘IO次数都一样(体现稳定性)

(3)叶子结点是数据的全集,所以在非叶子结点中,都是重复出现的数据,就可以把表每一行的数据,最终都关联到叶子结点这一层,非叶子结点就只需要保存一个key值(如id)即可

非叶子结点所占的空间比较小,就可以在缓存在内存中了,进而查询速度会比较快

3.3.索引背后是B+树的条件

基本条件:在innodb存储引擎下,……去创造一张表的时候。

(1)创造的表(不存在主键、外键、unique),此时表会有默认主键,会根据该主键创建表,此时表索引的背后不是B+树

(2)创造表时(存在主键、外键、unique等),就会根据主键列生成一个索引,从而根据索引创造B+树;此时,表索引背后的数据结构就是B+树,而整个表的数据就会存储在这棵B+树中

(3)在创建表之后,对某列设置索引,索引背后会再生成一棵独立的B+树

3.4.数据如何存储

这里介绍有索引且索引背后的数据结构是B+树的情况下,也就是B+树是如何存储插入表中的数据的

(1)主键索引B+树

前提:主键索引就是创造表的时候根据主键生成的一个索引,该索引背后的数据结构就是B+树

这样的一棵B+树,非叶子结点只存储主键列的值(例如id,也就称为key值),只有在叶子结点才会存储一整行的数据

当插入数据的时候,那一行数据会拿着key值去遍历b+树,找到合适的位置(也就是叶子结点层),才将整行数据存入叶子结点中。(此时非叶子结点也会存储着key值)

(2)非主键索引B+树

前提:非主键索引是在表已经存在的时候,给表中的某一列创造索引,该索引的背后也是B+树

此时,非叶子结点上面存储的也只有一个key(就是在哪一个列上设置的索引,key值就是那个列的值),在叶子结点上面,存储的则是之前主键的key值(拿到这个key值,再去遍历之前的B+树)

3.5.查询操作

(1)非索引非主键查询:在select时,where后面限制的列不存在索引,就会根据从B+树最左边的叶子结点开始遍历,俗称(链表查询),查询速度不会提升(非索引查询)

(2)主键索引查询:在select时,查询的是列是主键(主键列肯定有索引),就会从B+树起始位置开始查询(二叉搜索树查询)

(3)非主键索引查询:在select时,查询的是索引列但是非主键列,也是从B+树起始查询,拿到主键id后再回到主键列的B+树进行查询(查询两次)

事务

事务的四大特性(功能):原子性、一致性、持久性、隔离性

1.介绍事务

(1)背景引入

在执行多个SQL语句时,可能会发生这些情况:程序崩溃、系统崩溃、网络断开、主机掉电了……可能会导致前面SQL语句执行成功,而后面的SQL语句执行失败

(2)背景发生

在A向B转账的过程中,由于一些失误,就会导致A的钱转出去了,但是B却没有收到钱

(3)事务的概念

为了防止上述等情况的发生,引入事务的概念

事务,就是把多个操作打包成一个整体(操作)

(4) 事务的保证

将多个操作打包成一个操作后,就能保证整体要么执行成功,要么都执行失败。可以避免只有一部分操作执行成功,避免产生一些问题

(5)突出”原子性“

将多个操作打包成一个操作,则体现事务的原子性

2.事务的四大特性

2.1.原子性

(1)背景

前面说到,事务可以保证整个操作要么执行,要么失败,结果是这样子展示的,但是他的过程却不是这样子的。

(2)事务的回滚机制

事务中的多个sql语句也是一条一条执行,但是事务可以保证,在事务中的sql语句出现问题时,可以将他恢复回去,就行如没有执行过sql语句一样,一般术语称为翻新,在mysql中,称为回滚(rollback)

1.为了实现事务的回滚机制,事务在执行的时候都会记录日志。

2.日志就是可以记录一些操作,比如sql语句是怎么执行的,执行了删除还是插入操作

如何回滚(在执行事务的过程中出现了问题,只要数据库处于正常工作状态,都能恢复):

1)之前执行了新增操作,就把插入的数据删除掉

2)之前执行了删除操作,就会把数据新增上来

3)之前进行了修改操作,就会把数据该回去

4)之前是查询操作,则没有任何影响,不进行任何的恢复操作

在执行完事务操作后,这些日志通常会被删除

(3)事务、原子性、日志关系

日志保证了事务回滚机制的进行,回滚机制又保证了事务的原子性(也成为功能)

2.2.事务的一致性

(1)性质体现

事务执行之前,和事务执行完毕后,可以保证执行前的状态是一致的,执行后的状态也是一致的,也就是保证数据的正确性。

2.3.持久性

(1)在执行完事务之后,可以保证数据在硬盘上持久存储,重启后仍然存在

(2)保证事务的每一次操作对数据的改变都是“永久”的

2.4.隔离性

隔离性主要是为了确保事务执行的成功,防止被其他的事务干扰(其他的事务不可见)。

在执行并发事务时,没有实现隔离时会产生的问题:

(1)脏读问题

问题实质:在数据库中,如果有事务A和事务B;事务A针对某个表做出了一些修改,在事务A提交之前(未修改完),事务B就对这里的数据进行了读取,最终就可能出现A后续的操作又把上述的数据进行了修改,导致事务B读到的数据和A提交的数据是不相同的。

做法:对写操作加上锁,称为写加锁操作

结果:加了锁之后,在事务A执行写操作的时候,事务B就不能执行了,需要等待A执行完。

导致:降低了“并发能力”,变相降低了数据库服务器的处理效率;但是提高了“隔离性”,也提高了数据的准确性。

(2)不可重复读问题

存在三个事务A,B,C

问题实质:事务A针对数据进行修改提交,接下来事务B进行读取数据(里面有多个sql语句都要进行读操作),在执行B的过程中,有一个事务C也参与了进行,并且对数据进行了修改。导致B里面不同的读操作,读到的结果是不一样的

做法:引入读加锁

结果:在读取数据的时候,也不能进行任何的写操作

导致:又会使“并发程度”进一步降低,效率也会降低,而“隔离性”又进一步提高,数据的准确性也得到提高(ABC都不能进行并发操作)

(3)幻读问题

问题实质:事务A修改并提交数据,事务B进行读数据,此时C给对应的表进行了新增数据/删除数据等操作,使得事务B读到的数据集是不同的(内容一样,数量不一样)

做法:实现串行化的方式,使所有的事务按照一个接一个的执行

后果:所有事务只能一个接一个执行

导致:此时,完全没有并发性,执行效率最低,隔离性最高,数据也是最准确的

(4)总结

问题:脏读问题和不可重复读问题,一般都是由于一个事务在读操作时,其他事务对内容数据进行了修改,导致读取的内容前后不一样;而幻读问题,是由于一个事务在读操作时,其他事务进行了插入/删除操作,导致数据的数量发生变化。

做法总结:

1)脏读:事务B读到了事务A中未提交的临时数据(脏数据)==>写加锁

2)不可重复读问题:事务B读的过程中,又有一个事务C对刚才事务A提交的数据进行了修改,使事务B内部不同的读操作读到的结果是不同的==>读加锁

3)幻读:类似不可重复读,事务B读的过程中,事务C没有修改数据内容,而是修改了“结果集”,导致B内部不同的读操作读到的数量不一样==>串行化

所以:

事务的隔离性,就是提供了几个隔离等级供选择,可以针对不同的情况进行不同程度的隔离。

3.隔离等级

(1)read uncommitted:允许读取其他事务未提交的数据==>脏读+不可重复读问题+幻读 并发程度最高,隔离性最低

(2)read committed:只能读取其他事务提交后的数据==>解决了脏读,存在不可重复读+幻读,并发程度降低,隔离性提高

(3)repeatable read:针对读操作和写操作都加锁==>解决了脏读+不可重复读,存在幻读,并发程度又降低,隔离性又提高

(4)串行化(serializable):所有的事务都是串行执行的==>解决了脏读+不可重复读+幻读,并发基本没有,隔离性最高。

相关实践学习
日志服务之使用Nginx模式采集日志
本文介绍如何通过日志服务控制台创建Nginx模式的Logtail配置快速采集Nginx日志并进行多维度分析。
相关文章
|
2月前
|
存储 关系型数据库 MySQL
阿里面试:为什么要索引?什么是MySQL索引?底层结构是什么?
尼恩是一位资深架构师,他在自己的读者交流群中分享了关于MySQL索引的重要知识点。索引是帮助MySQL高效获取数据的数据结构,主要作用包括显著提升查询速度、降低磁盘I/O次数、优化排序与分组操作以及提升复杂查询的性能。MySQL支持多种索引类型,如主键索引、唯一索引、普通索引、全文索引和空间数据索引。索引的底层数据结构主要是B+树,它能够有效支持范围查询和顺序遍历,同时保持高效的插入、删除和查找性能。尼恩还强调了索引的优缺点,并提供了多个面试题及其解答,帮助读者在面试中脱颖而出。相关资料可在公众号【技术自由圈】获取。
|
15天前
|
Java 关系型数据库 数据库
京东面试:聊聊Spring事务?Spring事务的10种失效场景?加入型传播和嵌套型传播有什么区别?
45岁老架构师尼恩分享了Spring事务的核心知识点,包括事务的两种管理方式(编程式和声明式)、@Transactional注解的五大属性(transactionManager、propagation、isolation、timeout、readOnly、rollbackFor)、事务的七种传播行为、事务隔离级别及其与数据库隔离级别的关系,以及Spring事务的10种失效场景。尼恩还强调了面试中如何给出高质量答案,推荐阅读《尼恩Java面试宝典PDF》以提升面试表现。更多技术资料可在公众号【技术自由圈】获取。
|
29天前
|
SQL 关系型数据库 MySQL
阿里面试:1000万级大表, 如何 加索引?
45岁老架构师尼恩在其读者交流群中分享了如何在生产环境中给大表加索引的方法。文章详细介绍了两种索引构建方式:在线模式(Online DDL)和离线模式(Offline DDL),并深入探讨了 MySQL 5.6.7 之前的“影子策略”和 pt-online-schema-change 方案,以及 MySQL 5.6.7 之后的内部 Online DDL 特性。通过这些方法,可以有效地减少 DDL 操作对业务的影响,确保数据的一致性和完整性。尼恩还提供了大量面试题和解决方案,帮助读者在面试中充分展示技术实力。
|
2月前
|
存储 关系型数据库 MySQL
贝壳面试:什么是回表?什么是索引下推?
在40岁老架构师尼恩的读者交流群中,近期有成员获得了得物、阿里、滴滴等一线互联网企业的面试机会,遇到了诸如“MySQL索引下推”、“回表查询”等重要面试题。由于缺乏准备,部分成员未能通过面试。为此,尼恩系统地整理了相关知识点,帮助大家提升技术实力,顺利通过面试。具体内容包括MySQL的架构、回表查询的工作原理及其性能问题、索引下推的底层原理和优势等。此外,尼恩还提供了优化建议和实战案例,帮助大家更好地理解和应用这些技术。尼恩的技术资料《尼恩Java面试宝典PDF》也收录了这些内容,供后续参考。
贝壳面试:什么是回表?什么是索引下推?
|
2月前
|
SQL 关系型数据库 MySQL
阿里面试:MYSQL 事务ACID,底层原理是什么? 具体是如何实现的?
尼恩,一位40岁的资深架构师,通过其丰富的经验和深厚的技術功底,为众多读者提供了宝贵的面试指导和技术分享。在他的读者交流群中,许多小伙伴获得了来自一线互联网企业的面试机会,并成功应对了诸如事务ACID特性实现、MVCC等相关面试题。尼恩特别整理了这些常见面试题的系统化解答,形成了《MVCC 学习圣经:一次穿透MYSQL MVCC》PDF文档,旨在帮助大家在面试中展示出扎实的技术功底,提高面试成功率。此外,他还编写了《尼恩Java面试宝典》等资料,涵盖了大量面试题和答案,帮助读者全面提升技术面试的表现。这些资料不仅内容详实,而且持续更新,是求职者备战技术面试的宝贵资源。
阿里面试:MYSQL 事务ACID,底层原理是什么? 具体是如何实现的?
|
2月前
|
Java 程序员 Spring
Spring事务的1道面试题
每次聊起Spring事务,好像很熟悉,又好像很陌生。本篇通过一道面试题和一些实践,来拆解几个Spring事务的常见坑点。
Spring事务的1道面试题
|
2月前
|
SQL 关系型数据库 MySQL
美团面试:mysql 索引失效?怎么解决? (重点知识,建议收藏,读10遍+)
本文详细解析了MySQL索引失效的多种场景及解决方法,包括破坏最左匹配原则、索引覆盖原则、前缀匹配原则、`ORDER BY`排序不当、`OR`关键字使用不当、索引列上有计算或函数、使用`NOT IN`和`NOT EXISTS`不当、列的比对等。通过实例演示和`EXPLAIN`命令分析,帮助读者深入理解索引失效的原因,并提供相应的优化建议。文章还推荐了《尼恩Java面试宝典》等资源,助力面试者提升技术水平,顺利通过面试。
|
4月前
|
索引
【面试题】串联所有单词的子串,找到所有符合条件的串联子串的起始索引
【面试题】串联所有单词的子串,找到所有符合条件的串联子串的起始索引
52 0
|
4月前
|
存储 Java
【IO面试题 四】、介绍一下Java的序列化与反序列化
Java的序列化与反序列化允许对象通过实现Serializable接口转换成字节序列并存储或传输,之后可以通过ObjectInputStream和ObjectOutputStream的方法将这些字节序列恢复成对象。
|
27天前
|
存储 缓存 算法
面试官:单核 CPU 支持 Java 多线程吗?为什么?被问懵了!
本文介绍了多线程环境下的几个关键概念,包括时间片、超线程、上下文切换及其影响因素,以及线程调度的两种方式——抢占式调度和协同式调度。文章还讨论了减少上下文切换次数以提高多线程程序效率的方法,如无锁并发编程、使用CAS算法等,并提出了合理的线程数量配置策略,以平衡CPU利用率和线程切换开销。
面试官:单核 CPU 支持 Java 多线程吗?为什么?被问懵了!

热门文章

最新文章