是否支持事务和崩溃后的安全恢复: MyISAM 强调的是性能,每次查询具有原子性,其执行速度比InnoDB类型更快,但是不提供事务支持。但是InnoDB 提供事务支持事务,外部键等高级数据库功能。 具有事务(commit)、回滚(rollback)和崩溃修复能力(crash recovery capabilities)的事务安全(transaction-safe (ACID compliant))型表。
是否支持外键: MyISAM不支持,而InnoDB支持。
是否支持MVCC :仅 InnoDB 支持。应对高并发事务, MVCC比单纯的加锁更高效;MVCC只在 READ COMMITTED 和 REPEATABLE READ 两个隔离级别下工作;MVCC可以使用 乐观(optimistic)锁 和 悲观(pessimistic)锁来实现;各数据库中MVCC实现并不统一
数据库事务四大特性原子性(Atomic)要么全做要么全不做
一致性(Consistency)数据要保持完整性,从一个一致状态到另一个一致状态,执行事务前后,多个事务对同一个数据读取的结果是相同的
隔离性(Isolation)一个事务的执行不影响其他事务
持久性(Durability)事务一旦提交,变更应该永久的保存到数据库中
事务隔离级别 隔离级别 脏读 不可重复读 幻读未提交读(Read uncommitted) 可能 可能 可能
已提交读(Read committed) 不可能 可能 可能
可重复读(Repeatable read) 不可能 不可能 可能
可串行化(Serializable) 不可能 不可能 不可能
Read uncommitted会出现的现象--->脏读:一个事务读取到另外一个事务未提交的数据
例子:A向B转账,A执行了转账语句,但A还没有提交事务,B读取数据,发现自己账户钱变多了!B跟A说,我已经收到钱了。A回滚事务【rollback】,等B再查看账户的钱时,发现钱并没有多。
出现脏读的本质就是因为操作(修改)完该数据就立马释放掉锁,导致读的数据就变成了无用的或者是错误的数据。
Read committed出现的现象--->不可重复读:一个事务读取到另外一个事务已经提交的数据,也就是说一个事务可以看到其他事务所做的修改
注:A查询数据库得到数据,B去修改数据库的数据,导致A多次查询数据库的结果都不一样【危害:A每次查询的结果都是受B的影响的,那么A查询出来的信息就没有意思了】
Repeatable read避免不可重复读是事务级别的快照!每次读取的都是当前事务的版本,即使被修改了,也只会读取当前事务版本的数据
至于虚读(幻读):是指在一个事务内读取到了别的事务插入的数据,导致前后读取不一致。
注:和不可重复读类似,但虚读(幻读)会读到其他事务的插入的数据,导致前后读取不一致
MySQL的Repeatable read隔离级别加上GAP间隙锁已经大概率处理了幻读了。
常用存储引擎适用场景MyISAM适用频繁执行全表count,查询频率高,增删改频率不高
InnoDB增删改查都频繁,对可靠性要求高,要求支持事务
锁粒度划分
表锁开销小,加锁快;不会出现死锁;锁定力度大,发生锁冲突概率高,并发度最低
行锁开销大,加锁慢;会出现死锁;锁定粒度小,发生锁冲突的概率低,并发度高
InnoDB默认行锁,也支持表锁,没有用到索引的时候用表级锁
MyISAM默认表锁
手动给表加锁 lock tables <read|write> , 解锁 unlock tables
共享锁(S):SELECT * FROM table_name WHERE ... LOCK IN SHARE MODE。
排他锁(X):SELECT * FROM table_name WHERE ... FOR UPDATE
InnoDB支持事务,关闭事务自动提交方法 set autocommit = 0
InnoDB锁种类Record lock:单个行记录上的锁
Gap lock:间隙锁,锁定一个范围,不包括记录本身
Next-key lock:record+gap 锁定一个范围,包含记录本身
MVCC和事务的隔离级别描述
数据库事务有不同的隔离级别,不同的隔离级别对锁的使用是不同的,锁的应用最终导致不同事务的隔离级别
MVCC(Multi-Version Concurrency Control)多版本并发控制,可以简单地认为:MVCC就是行级锁的一个变种(升级版)。
事务的隔离级别就是通过锁的机制来实现,只不过隐藏了加锁细节
特点
MVCC一般读写是不阻塞的(所以说MVCC很多情况下避免了加锁的操作)