欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 房产 > 家装 > MySQL索引事务

MySQL索引事务

2025/2/7 11:43:17 来源:https://blog.csdn.net/YQY18289570091/article/details/145457333  浏览:    关键词:MySQL索引事务

1.索引

概念

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


作用

数据库中的表、数据、索引之间的关系,类似于书架上的图书、书籍内容和书籍目录的关系。
索引所起的作用类似书籍目录,可用于快速定位、检索数据。
索引对于提高数据库的性能有很大的帮助。

索引属于针对查询操作引入的优化手段,可以通过索引来加快查询的速度,避免针对表的遍历

索引是能提高查询速度的,但是也是有代价的:

1.占用更多的空间,生成索引,是需要一系列的数据结构,以及一系列的额外的数据,来存储到硬盘空间中的。

2.可能会降低插入、修改、删除的速度


使用场景

要考虑对数据库表的某列或某几列创建索引,需要考虑以下几点:
数据量较大,且经常对这些列进行条件查询。
该数据库表的插入操作,及对这些列的修改操作频率较低。
索引会占用额外的磁盘空间。
满足以上条件时,考虑对表中的这些字段创建索引,以提高查询效率。
反之,如果非条件查询列,或经常做插入、修改操作,或磁盘空间不足时,不考虑创建索引。


使用

主键、unique、外键 都是 自动生成索引的

1)查看索引

show index from 表名;

如上图所示,我们在创建一个普通的表的时候,没有主键,没有外键,没有unique的时候,小编再去查看索引,发现是空的。

如上图所示,小编在创建student这个表时创建了一个主键,主编再次查看索引就会发现并非为空【一个索引是针对一个列来指定的,只有针对这一列进行条件查询的时候,查询速度才能够被索引优化】,即意思是,此处只针对id创建索引,使用id进行条件查询是很快的,但是如果使用where name = '' 这个是得不到优化的【仍然需要遍历表】。

如上图所示,是unique下的效果

如上图所示,是主键+外键下的索引


2)创建索引

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

如上图所示,在小编前面创建的student表的基础上,手动得将name这一列创建一个索引。

※ 创建索引操作也是一个危险操作【因为创建索引的时候,需要针对现有数据进行大规模得重新整理。如果当前表是一个空表或者是数据不多,此时创建索引就大概率没有问题;如果这个表本身就很大,创建索引,也很容易就把数据库服务器给卡住】一般来说,创建索引都是在创建表的时候就规划好了,一旦这个表已经投入使用很久了,有很多数据了,再想修改索引就很危险了。【如果非要创建,那应该怎么办?答:另外再搞一个机器,部署MySQL服务器,也创建同样的表,并且把表上得索引创建好,再把之前得机器上得数据导入到新的MySQL服务器上(导数据的过程可以控制节奏)】


3)删除索引

手动创建得索引可以手动删除,但是自动创建得索引是不能删除的

drop index 索引名 on 表明;

如上图所示,当我们删除idx_student_name这个索引【手动创建的】的时候是可以很顺利得删除的,但是当小编想删除classId索引【自动创建得外键索引】得时候,却被MySQL服务器狠狠拒绝了。

※ 同样的,删除索引操作也是一个危险操作,理由同上。


索引背后的实现原理

经过我们对于数据结构与数据库得匹配程度,所以数据库引入的索引是一个改进得树形结构.
B+树N叉搜索树

什么是B+树

1.B树

如上图所示,当一个树得节点上有4个数,就会被分成5个区间【每个节点得度是不确定的,一个节点上保存N个key就可以划分出N+1个区间,每个区间就可以衍生出一系列得子树了】。由于每个节点是在一个硬盘得区域中,一次读硬盘就读取出了全部节点(多个key),再进行几次比较。因此树得高度就大幅度降低了,一个节点中虽然是可以保存N个key的,但是也不是无限制的,当到达一定规模的时候就会触发结点的分裂;而当删除的元素到达一定数目的时候,也会触发节点的合并。

2.B+树

B+树是B树的改进,是针对数据库量身定做的数据结构。

1)B+树也是一个N叉搜索树,一个节点上存在N个key,划分成N个区间

2)每个节点上N个key中,最后一个,就相当于当前子树的最大值

3)父节点上的每个key都会以最大值的身份在子节点的对应区间中存在(key可能会重复出现→→意义:叶子这一层,包含了整个树的数据全集)

4)B+树会使用链表这样的结构,把叶子节点串起来 →→ 此时就可以非常方便得完成数据集合得遍历,并且很方便得从数据集合中按照范围取出一个“子集”。

如上图所示,在父树上有两个数字8、15,但是只分成了两个区间,而且左子树的最大值的8,右子树的最大值是15,即这一整棵树的最大值是15.

B+树的优点(相比于B树以及哈希,红黑树):

1)N叉搜索树,树的的高度非常有限,降低IO的次数

2)非常擅长范围查询

3)所有查询最终都是要落到叶子节点,查询和查询之间的时间开销是稳定的【换句话来说就是不会出现这次特别快下次特别慢的情况(即对于B树来说,要查询的元素如果在根节点或者层次比较高的节点就能很快得拿到元素,但是如果要查得元素在叶子节点,此时花的时间就会比较多。)】,而对于B+树来说,所有的查询都要最终到叶子上查询,无论查询哪个元素,整体得时间开销都是差不多。

4)由于叶子节点是全集,会把行数据只存储在叶子节点上,非叶子节点只是存储一个用来排序的key(比如说存个id)【数据库里是按行组织数据的,但是创建索引的时候是针对某一列创建的】,这一行数据内容是比较多的,而这一个id则是内容比较少的,叶子节点会非常占用空间,而非叶子节点则占用不了多少空间。

所以将非叶子节点缓存到内存中(硬盘上还要存这些非叶子节点,但是当我们进行查询的时候就可以把这些非叶子节点加载到内存中,整体查询的比较过程就可以在内存中进行了,又进一步得减少了IO访问次数)


2.事务

概念

事务指逻辑上的一组操作,组成这组操作的各个单元,要么全部成功,要么全部失败。在不同的环境中,都可以有事务。对应在数据库中,就是数据库事务。

事务的特点:

1.原子性:通过回滚的方式,保证这一系列的操作都能执行正确或者恢复如初

2.一致性:事务执行之前和之后,数据都不能离谱。【这里的一致性很多时候是要靠数据库的约束以及一系列的检查机制来完成的】

3.持久性:事务做出的修改,都是在硬盘上持久保存的。重启服务器,数据仍然还是在的,事务执行的修改仍然是有效的。


4.隔离性:数据库并发执行多个事务的时候涉及到的问题;如果我们希望数据库服务器执行效率高,就希望提高并发程度,但是提高并发程度之后,可能会存在数据出现错误等一系列的问题。【如果两个事务之间的影响越大隔离性就会越低,影响越小隔离性就会越高】

1.脏读问题:一个事务A正在修改数据的过程中,另一个事务B读取了同一个数据,但是接下来事务A又修改了数据,导致B之前读到的数据是一个无效的/过时的数据(也称脏数据)

解决方案:核心思路就是针对写操作进行加锁,是并发程度降低

2.不可重复读问题:并发执行事务过程中,如果事务A在内部对此读取同一个数据的时候,出现了不同的情况,这种就是不可重复读。【即事务A在两次读之间,有一个事务B修改了数据并提交了事务】

解决方案:解决不可重复读的问题是需要给读操作加锁的【即在事务A读的时候,事务B是不可以修改的】,并发程度又进一步降低了,隔离性也进一步提高了,效率降低了,数据的准确性又提高了。

3.幻读问题:根据上面两个问题,我们是分别通过写加锁和读加锁这两个操作来进行解决的。但是虽然约定事务B读A文件的时候,事务A不能写A文件,但是事务A可以写B文件啊。这里的问题是虽然事务A没有修改A文件,但是这个结果集突然迸出了一个B文件【即一个事务A执行过程中,两次的读取操作,数据内容虽然不变,但是结果集变了,这种称为“幻读”】

解决方案:【我们知道解决这类问题的核心就是降低并发程度】引入串行化的方式,解决幻读,保持绝对的串行执行事务,此时完全没有并发了。【其实上述三个问题都是并发程度带来的问题】

※ 而隔离级别就是在“数据正确”和“效率”之间做权衡【往往提高了效率就会牺牲正确性,提升了正确性就会牺牲效率】。所以说“正确性”和“效率性”是鱼和熊掌不可兼得的,则我们需要在不同的业务场景中做出一定的取舍。【即有些场景追求正确性(例如充值、转账...);那有些场景追求效率(例如短视频点赞、评论、投币、评论、转发...)】

四种隔离级别

1.read uncommitted(读未提交):并发程度最高,速度最快,隔离性最低,准确性最低

2.read committed(读已提交):引入了写加锁,只能读写完之后提交的版本。【并发程度降低了,速度降低了,隔离性降低了,准确性提高了】

3.repeatable read(可重复读)【默认】:引入了写加锁和读加锁,写的时候不能读,读的时候不能写【并发程度又进一步降低了,速度降低了,隔离性提高了,准确性提高了】

4.serialiable(串行化):严格的按照串行的方式,一个一个得执行事务【没有并发,速度最低,隔离性最高,准确性最高】


使用

(1)开启事务:start transaction;

(2)执行多条SQL语句;

(3)回滚或提交:rollback/commit;
         说明:rollback即是全部失败,commit即是全部成功。[rollback一般是要搭配一些条件判断逻辑来使用的]

重点:回滚是怎么做到的?

回滚是通过日志【打印出来的内容,存储在文件中。即使是主机掉电,也不影响,一旦重新启动主机,MySQL也重新启动,就会发现回滚日志中有一些需要进行回滚的操作,于是就可以完成这里的回滚了】的方式记录事务中的关键操作,这样的记录就是回滚的依据。

面试题

问:谈谈你对“事务”的理解?

答:

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com