索引事务
Posted 4612
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了索引事务相关的知识,希望对你有一定的参考价值。
一、索引
1、定义
索引类似于书的目录,可加快查找的速度
注意:
1)索引需要在条件中命中该索引列才行,没有命中就不会提高查询效率
2)某些条件下不会使用索引。比如name列创建了索引,但是使用where name is null,就不会使用该列的索引(因为索引没有保存null的信息)
2、常见的可用于查找的数据结构(数据库中构建索引时不采用以下三种结构)
1)线性表
查找速度比较慢,达不到高效
2)二叉搜索树(AVL树 、红黑树)
一、索引
1、定义索引类似于书的目录,可加快查找的速度注意:1)索引需要在条件中命中该索引列才行,没有命中就不会提高查询效率2)某些条件下不会使用索引。比如name列创建了索引,但是使用where name is null,就不会使用该列的索引(因为索引没有保存null的信息)**2、常见的可用于查找的数据结构(数据库中构建索引时不采用以下三种结构)**1)线性表查找速度比较慢,达不到高效2)二叉搜索树(AVL树 、红黑树)效率并不是很高,并且查找效率和树的高度是密切相关的
3)哈希表(速度快)
只能进行值相等的查找,不太方便进行值比较大小的范围查找
3、MySql 索引采取的数据结构B+树(N叉搜索树)
1)B+树的前身 —B树
B树中的每个节点不仅包含了索引列的数据(此处类比student表中的学生id),也包含了一行数据的其他列信息(类比student表中的name、classId…)
2)B+树
特点:
a)父节点里面的值,会作为子节点的最大值/最小值出现,这样就可以让所有的叶子节点包含了整体数据的全集
b)叶子节点按照顺序通过链表的方式连接起来了,这样就可以方便高效地实现范围查找了
c)每行树的其他列信息,只存在于叶子节点上,而非叶子节点仅仅包含索引列的数据,这样非叶子节点占有的空间就比较小了,就可以把这部分内容直接放到内存中,后续进行查找操作时,就可以主要去读内存,减少了很多次的磁盘操作
二、事务
举例:
有一个user表,其中包含的属性为用户id、账户余额acount,具体信息如下表所示
id | account |
---|---|
1 | 1000 |
2 | 500 |
1)所要进行的操作是:1给2转账200元
2)实现细节:把1的的余额-100,把2的余额+100
3)会出现的情况:
操作成功/由于系统故障,未能实现最后效果(所以为了解决这个问题,引入了事务)
1、事务
事务就是把若干个SQL语句给打包成一个整体,要么全都能执行完,要么就一个都不执行,就算是只执行了一部分,中间出了差错,数据库也能保证将已经改过的数据给自动还原成最初情况,这样的清理还原操作称为回滚(roll back)
2、事务的特性
1)原子性
2)持久性
事务执行完毕之后,数据就存储在磁盘上了,要是再重启主机,数据也仍然存在
3)一致性
事务执行完毕之后,数据仍是合理的(程序员手动定义的约束)
eg:上述转账操作,1最多只能给2转1000元,再多就不合理了
4)隔离性
并发执行事务所产生的问题和解决方案
3、mysql并发执行事务可能产生的问题及解决方案—都是与隔离性有关的
3.1脏读
一个事务A正在修改数据,另外一个事务B直接就读取A正在修改的数据,此时B读到的数据就是脏数据。因为此时B独到的数据很可能就在A的后续操作中又进行了修改,想当于B独到的数据只是一个”中间的状态“。独到的这个数据就是“脏数据”,这个动作,就叫“脏读”
举例:
小红在敲代码的时候,被小蓝窥屏,小蓝此时读到的代码就是一个中间状态的代码,小红很可能在后续操作中对这些代码进行修改,此时小蓝读到的数据就是“脏数据”,小蓝窥屏的动作就叫做”脏读”
- 解决脏读问题的方案—给写操作加锁
小红发现小蓝窥屏,就和小蓝约定好不许偷看,会在代码写完之后提交至码云,然后让小蓝从码云上看,这样就是给写操作加锁
3.2不可重复读
引入写加锁操作后,事务A修改数据然后提交,提交完毕之后事务B开始读取数据。事务B中包含多次读操作,如果在B 读数据的过程中,A对提交的数据进行修改再次提交,此时事务B两次读操作的结果不一样,这就是不可重复读
举例:小红将将代码提交至码云,小蓝在读过程中,读着读着就发现代码变了
- 解决不可重复读的方案—给读操作加锁
小红将代码提交至码云之后,小蓝开始读(写加锁),并且规定小蓝在读的时候小红不能对代码进行修改(读加锁)
3.3幻读
引入读加锁和写加锁操作后,事务B正在读取数据,事务A插入/删除了某些数据,事务B两次读到的数据集的个数发生了变化
举例:
由于引入了读加锁,即小蓝在读完代码之后小红才能进行对数据的修该,但是在小蓝读代码的过程中,小红可以创建一个相似的类(teacher)来对原来(student)类中的数据进行插入/删除操作并提交,小蓝读的时候就发现突然会冒出来一个teacher类,这就是“幻读”
-解决幻读的方案–串行化
彻底的让事务之间串行执行,此时就没有设计任何并发的事情了,即必须要的给一个事务执行完后,再执行后面的事务
总结:如果对于数据库的事务的事务的隔离性没有做出任何限制,此时脏读、不可重复读、幻读都存在。此时,通过读加锁解决脏读,通过写操作解决不可重复读,,通过串行化解决幻读。
- 隔离性:串行化>读加锁>写加锁
4、mysql中事务的隔离级别
1)read uncommitted —>没有做出任何隔离性的限制—>三个问题都存在—>执行效率最高
2)read committed—>相当于进行了写加锁,并发程度降低了,隔离级别就提高了,此时脏读问题被解决,但不可重复读,幻读仍存在
3)repeatable read —>相当于读写都枷锁,并发程度又降低了,隔离级别也相对提高了,此时脏读和不可重复读被解决,幻读仍然存在
4)Serializable串行化—>并发程度最低,隔离级别最高,此时脏读、不可重复读和幻读都被解决—>执行效率最低
事务日志用于保存:对数据的更新操作
执行同构的SQL、执行异构的SQL和调用存储过程分别调用的接口是:PreparedStatement、Statement、CallableStatement
关于PreparedStatement与Statement扫描的结果集和sql有关,与使用的jdbc操作对象无关
以上是关于索引事务的主要内容,如果未能解决你的问题,请参考以下文章