摸鱼聊面试笔记-数据库(一)

442 阅读3分钟

本文仅用作本人的笔记管理。

索引模块

主要记录和索引相关的笔记

为什么要使用索引

避免全表扫描,字典。大幅提升查询数据。 优点:

  • 快速查询数据

什么样的信息能成为索引

  • 主键、唯一键以及普通键

索引的数据结构

常用的数据结构有:

  • 生成索引,简历二叉查找树进行二分查找
  • 生成索引,建立B-Tree结构进行查找
  • 生成索引,建立B+-Tree结构进行查找
  • 生成索引,建立Hash结构进行查找

数据库事务的四大特性

数据库事务的四大特性可以简单地用四个字母表示:ACID。

  • A 原子性(Atomic) 表示事务包含的所有操作,要么全部执行,要么失败就全部回滚。

  • C 一致性(Consistency) 表示数据库是从一个一致的状态转向另一个一致的状态,满足完整性约束。比如A和B两人加起来一共有两千块。那么无论A向B转账或者B向A转账多少钱,他们加起来的一共也永远只有两千块。

  • I 隔离性(Isolation) 多个事务并发执行的时候,一个事务的执行并不会影响其他事务的执行。

  • D 持久性(Durability) 表示一个事务一旦提交,其修改就会永久地保存在数据库中。DBMS要求事务一旦提交,就要提供一定的冗余。比如MySQL就会把所有的操作都写入一个表,以便发生错误时时可以恢复。

事务隔离级别以及各级别下的并发访问问题

并发访问可能引起的问题

更新丢失

MySQL各级别的隔离级别在数据库层面均可避免。主要关注程序方面。

脏读

脏读指的是一个事务读到另一个事物的未更新数据。该问题可以在READ-COMMITED事务隔离级别以上可避免。

不可重复读

事务A多次读取统一数据,而在事务A读取的过程中,事务B对该数据进行了修改,从而使得事务A多次读到的数据不一致。

在REPEATABLE-READ事务隔离级别以上可避免。

幻读

事务A多次读取统一数据,而在事务A读取的过程中,事务B对该表新增或删减列,从而使得事务A多次读到的数据列不一致。

SERIALIZABLE事务隔离级别可以避免。

如图: 事务并发问题及避免

事务隔离级别越高,安全性越高,串行化执行越严重,降低并发度。MySQL 默认为REPETABLE-READ。

InnoDB可重复读隔离级别下避免幻读

当前读

加了锁的增删改查语句。
例如:select..lock in share mode,select ... for update,update,delete,insert

快照读

不加锁的非阻塞读,如select。仅在隔离级别低于SERIALIZABLE时属于快照读。

尽管可能是InnoDB的当前读使得避免幻读,但实质上真正能使得在REPETABLE-READ、SERIALIZABLE下避免幻读,还是靠next-key锁(行锁 + gap锁)。

何为next-key锁?

其包含两部分:行锁和gap锁。

行锁:行记录上的锁。 Gap锁:Gap是索引数中插入新纪录的空隙。Gap Lock锁定一个范围,不包括记录本身。防止同一事物的两次当前读出现缓堵的情况。 在RR及更低级别的情况下是没有。 RR及SERIABLE默认支持gap锁。

  • 如果where全部命中,则不会用gap锁,只会加记录锁。 全部命中,精确查询全都有。

  • 如果where条件部分命中或者全不命中,则会加Gap锁。

Gap锁主要用于在非唯一索引或者不走索引的当前读中。不过不走索引时应该尽量避免走Gap锁,因为会影响表效率。 Gap锁的范围为左开右闭。