面试你该知道的MySQL的锁与存储引擎

1. 文章开头先来说下MySQL是什么 (虽然都知道 还是顺序罗嗦一下)

2.MySQL 引擎

2.1 MyISAM存储引擎
  • 不支持事务
  • 不支持外键
  • 只支持表锁
  • 访问速度快
  • 对事务完整性没有要求,要求以select insert 为主的 应用基本上可以用这个引擎来创建表
2.2 InnoDB 存储引擎 // MySQL默认 存储引擎
  • 支持事务
  • 支持外键
  • 支持行锁和表锁
MEMORY 存储引擎
  • 查询快
  • 存在内存,会随时丢失,
  • 支持散列索引 和B树索引
  • 散列索引 ‘相等比较’ 时非常快,但对‘范围比较’ 速度就慢了,因此散列索引值 适合使用在和操作符,不适合或操作符,也同样不适合在order by 子句中使用
Archive存储引擎
  • 适合存储归档数据,如日志信息,
  • 只支持insert 和select 操作 其设计的目的是提供告诉的插入和压缩功能。

2. MySQL 索引

  • 提高MySQL的检索速度

  • 索引分为单列索引 和 组合索引 即一个索引只包含单个列,一个列可以有多个单列索引,但这不是组合索引 。组合索引 即一个索引包含多个列。

  • 索引会提高查询速度,同事会降低更新表的速度,如对表进行 insert update delete 。因为更新表的时候不仅要保存数据,还要保存一下索引文件。

  • 建立索引 会占用磁盘空间的索引文件。

创建索引 :

  • 普通索引

  • ALTER table tableName ADD INDEX indexName(columnName)

  • 唯一索引

  • CREATE UNIQUE INDEX indexName ON mytable(username(length))

正题

1. InnoDB 存储引擎

  • 使用InnoDB 的两大优点 : 一是支持事务,二是支持行锁

2 MySQL事务

在高并发的情况下事务的并发处理会带来的几个问题

  1. 脏读
    • 事务A 处理过程中读取到了事务B未提交的数据。
  2. 不可重复读
    • 一个事务执行的过程中 多次查询某一数据的时候结果不一致的现象,由于在执行过成功被另一个事务修改了数据并提交了事务。
  3. 幻读
    • 对一批数据的操作完成后,在其他事务有插入了满足条件的数据 导致的现象。
3.由于高并发事务带来的这几个问题,所以就产生了事务的隔离界别
  • Read uncommitted (读未提交) :最低级别,任何情况都无法保证
  • Read committed (读已提交) :可避免脏读的发生。
  • Repeatable read (可重复读):可避免脏读,不可重复读的发生。
  • Serializable (串行化) :可避免脏读, 不可重复读,幻读 。

4. InnoDB 常见的几种锁机制

  1. 共享锁和独占锁
  1. 意向锁
  1. 记录锁
  1. 间隙锁

    • 间隙锁是一种记录行与记录行之间存在空隙或者在第一行记录之前或在最后一行记录之后产生的锁,间隙锁可能占据的单行,多行或者空记录,
      通常的情况是我们采用范围查找的时候,比如在学生成绩管理系统中,如果此时有学生成绩 60,72,80,95,一个老师要查下成绩大于 72 的所有同学的信息,采用的语句是 select * from student where grade > 72 for update,这个时候 InnoDB 锁住的不仅是 80,95,而是所有在 72-80,80-95,以及 95 以上的所有记录。为什么会 这样呢际上是因为如果不锁住这些行,那么如果另一个事务在此时插入了一条分数大于 72 的记录,那会导致第一次的事务两次查询的结果不一样,出现了幻读。所以为了在满足事务隔离级别的情况下需要锁住所有满足条件的行。
  2. NK (记录锁和间隙锁的组合锁)

    • Next-Key Locks,NK 是一种记录锁和间隙锁的组合锁。是 2 和 3 的组合形式,既锁住行也锁住间隙。并且采用的左开右闭的原则。InnoDB 对于查询都是采用这种锁的。
  3. 乐观锁

    • 乐观锁,大多是基于数据版本( Version )记录机制实现。 何谓数据版本为数据增加一个版本标识,在基于数据库表的版本解决方案中,一般是通过为数据库表增加一个 “version” 字段来实现。 读取出数据时,将此版本 一同读出,之后更新时,对此版本 加一。此时,将提交数据的版本数据与数据库表对应记录的当前版本信息进行比对, 如果提交的数据版本 大于数据库表当前版本 ,则予以更新,否则认为是过期数据。
  4. 悲观锁

    • 悲观锁就是当我们去获取数据的时候,不论我们有没有打算去修改,悲观锁都会认为我们一定会去修改这个数据,所以 他会把这个数据直接锁死,其他的人想操作操作,那你就阻塞,直到轮到你获取锁为止。

乐观锁和悲观锁的区别
8. 乐观锁 总是认为不会产生并发问题,每次去取数据的时候总认为不会有其他线程对数据进行修改,因此不会上锁,但是在更新时会判断其他线程在这之前有没有对数据进行修改,一般会使用版本 机制或CAS操作实现。

  1. 悲观锁总是假设最坏的情况,每次取数据时都认为其他线程会修改,所以都会加锁(读锁、写锁、行锁等),当其他线程想要访问数据时,都需要阻塞挂起

文章知识点与官方知识档案匹配,可进一步学习相关知识MySQL入门技能树数据库组成存储引擎31327 人正在系统学习中

声明:本站部分文章及图片源自用户投稿,如本站任何资料有侵权请您尽早请联系jinwei@zod.com.cn进行处理,非常感谢!

上一篇 2019年4月26日
下一篇 2019年4月26日

相关推荐