数据库事务
在同一次执行中提交的多条语句,要么全部成功,要么全部失败,摆正了数据的一致性,
事务的四大特性:原子性、一致性、隔离性、持久性。
-
原子性:在事务中的增删改操作,要么全部执行,要么全不执行。
-
一致性:多个事务在数据相同的情况下结果必然相同。
-
隔离性:不同事务同时执行时不受未提交的事务中修改的数据影响。不会查到未提交事务修改的数据。
-
持久性:对于任意已提交事务,系统必须保证该事务对数据库的改变不被丢失,即使数据库出现故障。
事务产生问题与隔离级别
-
脏读:一个事务读取到另一个事务的未提交事务的数据。
-
不可重复读:一个事务读取另一个事务的提交的数据。(例一次事务中执行两次相同查询,两次结果不同)。
-
幻读:一个事务读取了另一个事务的插入的数据。(例一次事务中执行两次相同查询,第二次返回第一次没有的数据)。
隔离级别:读未提交,读已提交,可重复读,串行化。
级别越高效率越低。
-
读未提交:三种事务问题都会引发。
-
读已提交:可避免脏读,但仍会出现不可重复读和幻读。
-
可重复读:能够避免脏读和不可重复读,但仍不能避免幻读。MySQL默认级别。
-
串行化:所有事务串行执行,不在并行,即可避免所有事务问题。但效率最慢。
Spring事务的传播特性
-
propagation_required:当被调用方法已经在一个事务中,则继续在当前事务中执行,如果没在事务中,则新起一个事务。
-
propagation_supports:当被调用方法已经在一个事务中,则继续在当前事务中执行,如果没在事务中,则不以事务方式来执行。
-
propagation_mandatory:当被调用方法已经在一个事务中,则继续在当前事务中执行,如果没在事务中,则直接抛出异常。
-
propagation_required_new:不管当前是否已经在事务中,都新起一个事务,如果当前已经在事务中,则将其挂起,等待当前事务执行完毕。
-
propagation_not_supports:任何情况都不以事务方式执行,如果当前已经在事务中,则将事务挂起,继续以非事务方式执行结束再开始执行。
-
propagation_never:不以事务方式执行,如果当前已经再事务中,则抛出异常。
-
propagation_nested:不管当前是否已经在事务中,都新起一个事务,如果当前已经在事务中,则将其挂起,等待当前事务执行完毕。与propagation_required_new的区别是,propagation_nested模式时外层事务回滚,内层事务也会回滚,而内层事务回滚时外层事务不会回滚。
MySQL由什么组成
-
连接器:不管是JDBC还是数据库客户端,都需要连接MySQL服务器,连接的工作由连接器完成。
-
查询缓存(5.8版本开始删除掉了):执行select语句之前会查询缓存,如果缓存中存在则直接返回,不存在才会去执行查询。当select语句中涉及ide表发生数据修改时缓存立刻失效。
-
语法分析器:执行SQL之前解析,解析之后才可以执行。
-
优化器:解析完成以后对SQL进行优化,以提升执行效率。
-
执行器:执行最终SQL,返回执行结果。
MySQL怎么实现乐观锁与悲观锁
-
乐观锁:添加一个版本号或者时间戳字段,再更新时判断此字段是否与原来的值相等,不等则重试。
-
悲观锁:关闭MySQL的自动提交属性,通过事务的方式实现。
MySQL索引
维护数据库表索引的一种数据结构,通常使用B树或者B+树,这些数据结构能够在查询的时候更快的找到对应的行。
副作用:对索引相关字段进行增删改时,因为涉及到索引变动,所以会影响效率。
索引类型:
-
普通索引:顾名思义,最常见的索引。
-
唯一索引:此索引的值必须唯一,反对那是允许出现空值。如果是组合索引,则组合方式必须唯一。
-
主键索引:最特殊的一种索引,一个表中只能有一个主键索引,同时不允许有空值。
-
组合索引:创建索引时引用了多个字段,使用时需遵循最左前缀原则。
索引失效场景
-
查询条件中使用不等于号。
-
查询条件中使用了函数。
-
join on关联表时只有主键与外键会使用索引,即使使用其他字段也不会使用索引。
-
查询条件中使用了 LIKE和REGEXP ,只有在最左面非通配符的位置会使用索引。
-
使用组合索引时没有遵循最左前缀原则。
-
如果条件中有or(并且其中有or的条件是不带索引的) 。
-
如果列类型是字符串,那一定要在条件中将数据使用引号引用起来,否则不使用索引。
-
如果MySQL分析全表扫描比索引还要快的时候。
聚集索引与非聚集索引区别
-
聚集索引:其中索引内容的顺序与表记录的物理顺序相同,找到了一条再找下一条就方便了,就好像查字典查到了孤,再找估就方便了,因为都是挨着的。同时因为同一张表中记录的物理顺序只会有一种,所以同一张表中也只会有一个聚集索引。
-
非聚集索引:其中索引内容的顺序与表记录的物理顺序不同,所以可以创建多个非聚集索引。
聚集索引与非聚集索引的最大区别就是索引顺序与表记录物理顺序是否相同。
此问题没有搞透,复习时需要多注意。
SQL优化方案
-
开启慢SQL日志,找到执行速度慢的SQL。
-
通过explain分析SQL,找到执行慢的原因。
-
根据原因去对应的优化SQL。
执行查询时尽量让其通过索引查找,如果没走索引则参考上一条。
组合索引的最左原则
使用组合索引时会优先使用最左侧的字段,之后再去匹配下一个字段。
例如一个组合索引为(A、B、C)
select * from test order by A,会走索引;
select * from test order by A,B,会走索引;
select * from test order by A,B,C,会走索引;
select * from test order by B,不会走索引;
行锁、表锁和页锁?
-
行锁:开销大,可能出现死锁;但是粒度小,出现冲突概率低。
-
表锁:开销小,不会出现死锁;但力度打,出现冲突概率高。
-
页锁:介于行锁与表锁中间的一种锁,优点和缺点都是在他们俩中间。
数据库的三范式
-
第一范式:堆属性的原子性约束:每一列都是不可分割的。(例如某一字段值为省市区,则不符合第一范式,将其改为三个字段分别存放省、市、区)。
-
第二范式:对记录的唯一性约束,一张表只干一件事。(例如成绩表中还保存学生信息)
-
第三范式,对字段冗余性的约束,要求字段没有冗余。(例成绩表中除了学生ID字段还有学生姓名字段)