mysql学习
一、事务
就是一堆操作,看成一个操作。然后解决可能存在的问题。
(1)ACID原则
- A(Automic) 原子性
事务里面的操作是一个整体。操作就像原子一样,不可分割
- C(Consistency) 一致性
事务里面的操作集的结果要么全成功,要么全失败。没有中间状态。
- I(Isolation) 隔离性
事务之间的数据操作,存在相互的影响,mysql设计了四种策略来实现。
- D(Durability) 持久性
事务一旦提交,就是永久性的,其他的操作和设备故障不影响操作结果。
(2)实现事务需要三个工具, 日志文件、锁机制、MVCC。
日志文件
事务要想解决处理前和处理后一致性,就需要有标识记录修改前和修改后的状态,mysql针对修改前和修改后提供了两个日志文件 -- undo log和redo log。
redo log是用来恢复数据的 用于保障已提交事务的持久化特性。
undo log 记录事务修改之前版本的数据信息,因此假如由于系统错误或者rollback操作而回滚的话可以根据undo log的信息来进行回滚到没被修改前的状态。
MVCC
是通过在每行记录的后面保存两个隐藏的列来实现的。实现某种版本机制
只在读已提交与可重读中工作,分离数据的修改
trx_id
:表示最近修改的事务的id ,每次一个事务对某条聚簇索引记录进行改动时,都会把该事务的事务id
赋值给trx_id
隐藏列。新增一个事务时,trx_id会递增,因此 trx_id 能够表示事务开始的先后顺序。roll_pointer
:指向该行上一个版本的地址,每次对某条聚簇索引记录进行改动时,都会把旧的版本写入到undo日志
中,然后这个隐藏列就相当于一个指针,可以通过它来找到该记录修改前的信息。
锁机制
请看二
(3)事务隔离级别存在的问题
- 脏读
多个事务操作,能读取到其他事务未提交的数据
- 不可重复读
同个事务中,相同查询语句的结果不一样。因为其他事务提交造成相同sql查询的数据不一致
- 幻读
两个不同的事务中,事务a更具条件修改数据,事务b添加一条数据,且数据符合a中的条件,但是数据是不会被a修改,就像没发生过。
(4)事务隔离性
- 读未提交
可以读取到其他事务未提交的数据
- 读已提交
可以读到其他事务提交的数据,解决上级事务的脏读问题。
事务中重复查询都会重新生成readView,因为想看见其他事务提交的数据,数据版本需要更新,所以重新查询
- 可重复读
mysql8默认的隔离级别,解决不可同事务中,读取的数据数值不一致问题
事务中重复查询都会复用第一次查询的readView,事务的版本已经确定,保证前后一直,直接复用以前的版本
- 串行化
事务执行串行化,顺序执行
读的时候共享锁
写的时候直接排它锁
二、锁
在并发事务执行中,如果某个事务想要写操作某条数据,如果这条数据有锁,必须等待这个锁的释放,然后才能执行。
mysql锁的基本单位是next-key lock(由记录锁和间隙锁组成),前开后闭为记录锁,前开后开为间隙锁
(1)行锁
操作分类
- 共享锁
- 排它锁
当insert、update、delete走索引的时候,对记录行进行行锁
select可以手动添加排它锁与共享锁 for update(排他锁 行级使用) lock in share mode(共享锁、表级使用)
排它锁和共享锁区别(亲测)
共享锁可以重复添加共享锁,排他锁添加后则不能添加任何锁
并不像大多数博客记录的那样,排他锁添加后,其他事务不能对该数据读写,任然是可以读的!
(2)表锁(共享锁)
实质为共享锁,多个事务同时进行的时候,没有获得锁的事务只能读,不能写数据
(3)多事务操作结果
transaction
事务只有执行到某条锁表语句的时候,才会锁记录或表,开启事务不会锁
创建事务的时候,默认提交当前事务,并释放表锁
insert
插入数据会行锁
update、delete
不走索引修改数据,会锁表,走索引会行锁
select
通过添加特殊字段,让数据加锁
三、索引
(1)索引类别类型
主键索引:是一 种特殊的唯一索引它还多了一个限制条件,要求键值不能为空。主键索引用primay key 创建。
普通(Normal):也叫非唯一索引,是最普通的索引,没有任的限制。
联合索引:多个字段创建的索引,使用时遵循最左前缀原则。
唯一 (Unique):索引列中的值必须是唯一的,但是允许为空值。
空间索引:MySQL5.7之后支持空间索引,在空间索引这方面遵循OpenGIS几何数据模型规则。
(2)索引结构类型
- 哈希索引: 适合等值查询,检索效率高,一次到位。
- B+树索引:所有数据存储在叶子节点,复杂度为O(logn),适合范围查询。
- FullText全文索引,针对数据比较大,like查询的那种