目录
这篇文章后续补充完整。
1、事物有哪些基本要素/或者有哪些必须满足的条件?
原子性:一个事物的所有操作,要么全部成功,要么全部失败,不会结束在中间某个环节。事物在执行过程中,某个环节执行失败了,会进行回滚,回到事物执行前的状态。
一致性:事物开始前和结束后,数据库的完整性约束没有被破坏,数据不存在中间状态,比如A向B转账,不可能存在A扣了钱,B没收到的数据状态。
隔离性:数据库允许多个并发事务同时对其数据进行读写和修改的能力,隔离性可以防止多个事务并发执行时由于交叉执行而导致数据的不一致。
[同一时间,只允许一个事务请求同一数据,不同的事务之间彼此没有任何干扰]
事务隔离分为不同级别,包括读未提交(Read uncommitted)、读提交(read committed)、可重复读(repeatable read)和串行化(Serializable)。
持久性:事务处理结束后,对数据的修改就是永久的。
2、多线程操作事物时,存在哪几种问题?
脏读:
指一个事物在处理过程中,读取了另一个事物未提交的数据。
不可重复读:
指对数据库中同一个数据,一个事物在执行过程中多次查询,返回了不同的数据值,这是由于该数据被另外一个事物修改了(区别于脏读,另外一个事物是已修改并提交)
[读到了被更新的数据]
幻读:
指当前事物读取了另一个事物提交的 [新增] 数据。区别于不可重复读,例:一个数据第一次读,没有;第二次读,突然有了。
3、针对多线程操作事物存在的问题,事物分哪几种 隔离级别?
事务隔离级别 | 脏读 | 不可重复读 | 幻读 |
未提交读(read-uncommitted) | 是 | 是 | 是 |
未提交读(read-committed) | 否 | 是 | 是 |
可重复读(repeatable-read) | 否 | 否 | 是 |
串行化读(serializable) | 否 | 否 | 否 |
未提交读:允许读取未提交事物修改的数据,因此无法避免脏读、不可重复读和幻读问题
已提交读:只能读取到已提交的数据。仅能避免脏读问题,是多数数据库的默认级别
可重复读:指一个事务过程中,该事务读取到的数据,都是事务开始时的数据快照,InnoDB默认级别,可避免脏读、不可重复读问题
串行化读:完全串行化的读,每次读都需要获得表级共享锁,读写互相阻塞
4、mysql 锁 和 MVCC?
mysql 锁分类:
表锁:对整表加锁,分读锁和写锁,会导致并发能力下降
行锁:对数据行加锁,并发能力强
MVCC 多版本并发控制
用途:普通读 不加锁;并且读写不冲突,避免读操作的加锁解锁耗时
5、mysql数据结构为什么是B+树?
参考:
http://www.liuzk.com/410.html
https://www.cnblogs.com/leefreeman/p/8315844.html
上文我们已经说明单个叶子节点(页)中的记录数=16K/1K=16。(这里假设一行记录的数据大小为1k,实际上现在很多互联网业务数据记录大小通常就是1K左右)。
那么现在我们需要计算出非叶子节点能存放多少指针,其实这也很好算,我们假设主键ID为bigint类型,长度为8字节,而指针大小在InnoDB源码中设置为6字节,这样一共14字节,我们一个页中能存放多少这样的单元,其实就代表有多少指针,即16384/14=1170(非叶子节点数)。那么可以算出一棵高度为2的B+树,能存放1170*16=18720条这样的数据记录。
根据同样的原理我们可以算出一个高度为3的B+树可以存放:1170*1170*16=21902400条这样的记录。所以在InnoDB中B+树高度一般为1-3层,它就能满足千万级的数据存储。在查找数据时一次页的查找代表一次IO,所以通过主键索引查询通常只需要1-3次IO操作即可查找到数据。
不使用B树原因?
因为B树不管叶子节点还是非叶子节点,都会保存数据,这样导致在非叶子节点中能保存的指针数量变少(有些资料也称为扇出),指针少的情况下要保存大量数据,只能增加树的高度,导致IO操作变多,查询性能变低;