from -> on -> join -> where -> group by -> 聚合函数计算 -> having(过滤聚合函数值) -> select -> distinct -> order by -> limit二、事务
事务是一个或多个dml组合的工作单元,要么全部执行 要么全部执行失败。
1、事务的特性:
(1)原子性:事务是一个整体,不可分割,要么全部执行 要么全部执行失败。
(2)隔离性:一个事务的执行不被其他事务所干扰。
(3)持久性:一旦事务提交,对数据的改变就是永久的。
(4)一致性:事务完成后,数据保持一致,不会多,不会少。
2、事务的隔离级别:
3、事务实现的原理:
3.1、原子性原理:通过mysql回滚日志undo log来实现的,事务进行时 inodb会生成undo log日志,如果事务失败或者回滚就利用undo log日志中的信息将数据进行修改
3.2、隔离性原理:利用mvvc 并发版本控制和锁机制实现
① mvvc实现思路是:对每一行数据用 undo log 记录多个版本的事务链,比较事务ID 决定数据是否显示出来,从而实现不同事务之间的隔离性。
MVCC 具体实现实现核心是
- 隐藏的字段(事务id和指针指向)
- undo log
- readView(快照读的视图保存着数据库某个时刻的数据信息)
流程:
- 获取多个版本事务的id 链
- 读数据获取Readview(有已提交事务id和未提交事务id)
读提交级别下 多次读取的ReadView不一样
可重复读级别下 多次读取的ReadView都是第一次·的
- Readview最新提交的事务id就是期望查到的数据
通过mvvc可让读写之间不阻塞提升并发处理能力,降低死锁概率
②读锁共享解决不可重复度
③写锁排他解决脏读
④间隙锁解决幻读(当前读)
4、持久性实现的原理:
利用 redo log 实现的 当向数据库写入数据时,执行过程会先写入Buffer Pool,Buffer Pool中修改的数据会定期刷新到磁盘中(这一过程叫做刷盘),这整一过程称为redo log。redo log 分为:
- Buffer Pool内存中的日志缓冲(redo log buffer),该部分日志是易失性的;
- 磁盘上的重做日志文件(redo log file),该部分日志是持久的。
如果MySQL宕机,而此时Buffer Pool中修改的数据在内存还没有刷新到磁盘,就会导致数据的丢失,事务的持久性无法保证。
- 解决:为了确保事务的持久性,在当事务提交时,会调用fsync接口对redo log进行刷盘
4、一致性实现的原理:
通过事务的原子性、持久性和隔离性来保证的
一致性指的是事务不能破坏数据的完整性和业务的一致性 :
- 数据的完整性: 实体完整性、列完整性(如字段的类型、大小、长度要符合要求)、外键约束等
- 业务的一致性:例如在银行转账时,不管事务成功还是失败,双方钱的总额不变。
存储引擎就是数据的存储技术
1、InnoDB与MyISAM的区别
- 事务:MyISAM不支持事务,InnoDB支持事务
- 主键和外键:MyISAM允许没有主键的表存在,不支持外键。InnoDB的必须要有主键
- MyISAM是表级锁,并发性能较差,但不容易发生死锁
- MyISAM:保存有表的总行数,如果 select count() from table 会直接取出该值InnoDB:没有保存表的总行数,如果 select count() from table 要遍历整个表
索引是高效获取数据的数据结构,类似目录能提高数据的查询性能
优点:提高数据的检索效率,保证行的唯一性。
缺点:占用空间,增删都需要动态的取维护。
- 聚簇索引:数据与索引放在一起,它的叶子结点存着整行数据 是一种存储数据的方式
- 非聚簇索引:数据与索引分开,它的叶子结点存着主键
当数据库中多个事务并发存取同一数据的时候,可用读写锁解决。(锁机制是阻塞的会影响性能)
按锁的粒度划分:表级锁、行级锁、页级锁;
按锁的类型划分:共享(锁S锁)、排他锁(X锁);
按锁的使用策略划分:乐观锁、悲观锁;
- 读锁(共享锁):多个事务可以对同一数据行共享一把读锁,只能进行读不能修改;
- 写锁(排它锁):一个事务获取排它锁之后,可以对锁定范围内的数据行执行写操作,在锁定期间,其他事务不能再获取这部分数据行的锁(共享锁、排它锁),只允许获取到排它锁的事务进行更新数据。
SELECT … LOCK IN SHARE MODE:加共享锁(开启事务,利用索引)
SELECT … FOR UPDATE:加排他锁(开启事务,利用索引)
INSERT / UPDATE / DELETE:加排他锁
- 表锁:当事务要在记录上加上行锁时,则先在表上加上对应的意向锁。之后事务如果想进行锁表,只要先判断是否有意向锁存在,存在时则可快速返回该表不能启用表锁,否则就需要等待,提高效率。



