一、事务
1、定义:满足ACID特性的一组操作,可以通过Commit提交一个事务,也可以使用Rollback进行回滚。
2、ACID
(1)原子性(Atomicity):事务被分成最小不可分割单元,要么全部提交成功,否则全部失败回滚。
(2)一致性(Consistency):数据库在事务执行前后保持一致状态。所有事务对同一数据读取结果相同。
(3)隔离性(Isolation):一个事务在最终提交前,对其他事务不可见。
(4)持久性(Durability):一旦事务提交,则做所修改永久保留在数据库中,即使系统崩溃,事务执行结果不会丢失。
MySQL采用AUTOCOMMIT模式,不显示使用START TRANSACTION,每次查询都会被当作一个事务自动提交。
二、并发一致性问题(难保证隔离性)
1、修改丢失:T1和T2 都要对某一个数据进行修改,T1先修改,T2随后修改,则T2的修改结果覆盖了T1的结果。
2、 读脏数据:T1修改一个数据,T2读入这个数据,结果T1撤回修改数据,T2读取的数据就是脏数据。
3、不可重复读:T2读取一个数据,结果T1修改这个数据,如果T2再读这个数据和第一次读取结果不同。
4、幻读:T1读取某个范围内的数字,T2在这范围中插入一个数据,T1再读入这个范围数据和上次结果不同。
通过并发控制可以改善。1)封锁2)数据库自身隔离级别机制。
三、封锁(锁定需要修改的那部分数据)
1、粒度:
(1)行级锁:力度小,成本高、并发行高。
(2)表级锁:力度大、成本小、不会出现死锁。
2、类型:
(1)读写锁:
a)排他锁(X锁、写锁):eg:行级锁。可以读取和更新。加锁期间不能再加其他锁。
b)共享锁(S锁、读锁):eg:表级锁。可以读取、不能更新。加锁i期可加S锁不能加其他锁。
(2)意向锁:支持多粒度封装。在读写锁基础上引入IX/IS。IX和IS是表锁,表示一个事务想要在表中某个数据行加X锁或S锁。这就要求一个事务在获得S/X锁之前必须获得表的IS/IX锁或更强锁。
- | X | IX | S | IS |
X | X | X | X | X |
IX | X | √ | X | √ |
S | X | X | √ | √ |
IS | X | √ | √ | √ |
3、封锁协议
(1)三级封锁协议
a)一级封锁协议:事务T修改数据D必须加X锁,直到T结束释放锁。防止修改丢失问题。
b)二级封锁协议:在一级基础上,读取D时必须加S锁,读取完释放S锁。防止读取脏数据。
c)三级封锁协议:在二级基础上,读取D时必须加S锁,直到T结束释放锁。防止不可重复读问题。
(2)两段锁(加锁解锁)协议
可串行化调度:采用并发控制使得并发执行事务结果和某个串行执行的事务结果相同。两段锁协议是保证可串行化调度的充分条件。
(3)MySQL隐式与显式锁定
MySQL的InnoDB存储引擎采用两段锁协议。根据隔离级别自动加锁,并且这些锁在同一时刻被释放、这称为隐式锁定。
四、隔离级别
1、未提交读(READUNCOMMITTED)
事务正在修改还未提交但对别的事务可见。
2、提交读(READCOMMITTED)
事务正在修改还未提交但对别的事务不可见。
3、可重复读(REPEATABLEREAD)
同一事物对多次读同一数据相同。
4、可串行划(SERIALIZABLE)
强制事务串行执行。加锁实现。
五、多版本并发控制(MVVC)
定义:MySQL的InnoDB实现隔离级别的一种方式,实现提交读和可重复读。未提交读只读取最新数据。
1、版本号:
(1)系统版本号:开始一个新的事务版本号自动递增。
(2)事务版本号:事务开始时系统的版本号。
2、隐藏的列:
MVCC每行记录后面隐藏两列存储两个版本号。
(1)创建版本号:创建一个数据行得快照时的系统版本。
(2)删除版本号:删除版本号>当前事务版本号,表示该快照有效,否则表示快照被删除。
3、Undo日志
MVCC的快照存储在Undo日志,日志通过回滚吧一个数据行(Record)的所有快照连起来。
4、实现过程
对可重复读实现隔离。
(1)SELECT:把没有对一个数据行做修改的事务称为 T,T 所要读取的数据行快照的删除版本号必须是未定义或者大于 T 的版本号,因为如果小于等于 T 的版本号,那么表示该数据行快照是已经被删除的,不应该去读取它。
(2)INSERT:将当前系统版本号作为数据行快照的创建版本号。
(3)DELETE:将当前系统版本号作为数据行快照的删除版本号。
(4)UPDATE:将当前系统版本号作为更新前的数据行快照的删除版本号,并将当前系统版本号作为更新后的数据行快照的创建版本号。可以理解为先执行 DELETE 后执行 INSERT。
5、快照读与当前读
(1)快照读:
select * from table ...;
(2)当前读:
select * from table where ? lock in share mode;
select * from table where ? for update;
insert;
update;
delete;
六、Next-Key Locks
Next-Key Locks 是 MySQL 的 InnoDB 存储引擎的一种锁实现。Next-Key Locks 解决了幻影读问题。在可重复读(REPEATABLE READ)隔离级别下,使用 MVCC + Next-Key Locks 可以解决幻读问题。
1、Record Locks:锁定一个记录上的索引,而不是记录本身。如果表没有设置索引,InnoDB 会自动在主键上创建隐藏的聚簇索引,因此 Record Locks 依然可以使用。
2、Gap Locks:锁定索引之间的间隙,但是不包含索引本身。例如当一个事务执行以下语句,其它事务就不能在 t.c 中插入 11。
SELECT c FROM t WHERE c BETWEEN 10 and 20 FOR UPDATE;
3、Next-Key Locks:Record Locks+Gap Locks结合。(有点像分段)
七、关系数据库设计理论
1、函数依赖:
记 A->B 表示 A 函数决定 B,也可以说 B 函数依赖于 A。
如果 {A1,A2,... ,An} 是关系的一个或多个最小属性的集合,那么该集合就称为键码。
对于 A->B,如果能找到 A 的真子集 A',使得 A'-> B,那么 A->B 就是部分函数依赖,否则就是完全函数依赖。
对于 A->B,B->C,则 A->C 是一个传递函数依赖。
2、异常:
(1)数据冗余:主键对应实际值出现两次。
(2)修改异常:修改一条记录,但是承载这条记录的信息没有被更新。
(3)删除异常:其他信息连带丢失。
(4)插入异常:有先后关系这种,但是前面那个关系对应的实际数据还没有创建。
3、范式(处理以上4种异常)
高级别范式依赖于低级别。
(1)第一范式(1NF):属性不可分割。
(2)第二范式(2NF):每个非主属性完全函数依赖于键码。(分解)
(3)第三范式(3NF):非主属性不传递函数依赖于键码。
八、ER图
构成:实体、属性、联系。
1、E的三种联系
包含一对一(两个箭头),一对多(箭头指向多),多对多三种。
2、表示出多次出现的关系。
出现几次画几次线。
3、联系的多向性
多元联系
4、子类的表示
三角形表示Is-a连接类和子类。