数据库(MySQL)面试知识篇

1.介绍事务的的 4 个特性,及隔离性中不同的隔离级别

原子性(Atomicity)、一致性(Consistency)、隔离性(Isolation)、持久性(Durability)
1 、原子性
事务是数据库的逻辑工作单位,事务中包含的各操作要么都做,要么都不做
2 、一致性
事务执行的结果必须是使数据库从一个一致性状态变到另一个一致性状态。因此当数据库只包含成功事务提交的结果时,就说数据库处于一致性状态。如果数据库系统运行中发生故障,有些事务尚未完成就被迫中断,这些未完成事务对数据库所做的修改有一部分已写入物理数据库,这时数据库就处于一种不正确的状态,或者说是不一致的状态。
3 、隔离性
一个事务的执行不能其它事务干扰。即一个事务内部的操作及使用的数据对其它并发事务是隔离的,并发执行的各个事务之间不能互相干扰。
4 、持续性
也称永久性,指一个事务一旦提交,它对数据库中的数据的改变就应该是永久性的。接下来的其它操作或故障不应该对其执行结果有任何影响。

脏读幻读不可重复度:
脏读是指在一个事务处理过程里读取了另一个未提交的事务中的数据
不可重复读是指在对于数据库中的某个数据,一个事务范围内多次查询却返回了不同的数据值,这是由于在查询间隔,被另一个事务修改并提交了
幻读指一个事务(同一个read view)在前后两次查询同一范围的时候,后一次查询看到了前一次查询没有看到的行

MySQL数据库提供的四种隔离级别:
① Serializable (串行化):可避免脏读、不可重复读、幻读的发生。
② Repeatable read (可重复读):可避免脏读、不可重复读的发生。
③ Read committed (读已提交):可避免脏读的发生。
④ Read uncommitted (读未提交):最低级别,任何情况都无法保证。

2. MySQL 是否支持事务,默认使用哪种隔离级别。

mysql中用的最多的存储引擎有:innodb,bdb,myisam ,memory 等,其中innodb和bdb支持事务而myisam等不支持事务
InnoDB 引擎支持事务,默认使用可重复读(RR)隔离级别

3.InnoDB 如何实现不同的事务隔离级别,如何实现可重复读。

MVCC(多版本并发控制)是通过数据多版本来做到读写分离。从而实现不加锁读进而做到读写并行。InnoDB为每行记录添加了一个版本号(系统版本号),每当修改数据时,版本号加一。在读取事务开始时,系统会给事务一个当前版本号作为全局事务id,事务会读取版本号<=当前版本号的数据,这时就算另一个事务插入一个数据,并立马提交,新插入这条数据的版本号会比读取事务的版本号高,因此读取事务读的数据还是不会变。

MVCC在mysql中的实现依赖的是undo log与read view
undo log : undo log 中记录某行数据的多个版本的数据。
read view : 用来判断当前版本数据的可见性

4.说出一致性视图、事务 ID 划分,哪些事务修改对当前会话可见,哪些不可见

InnoDB 为每个事务构造了一个数组,用来保存这个事务启动瞬间,当前正在“活跃”的所有事务 ID。“活跃”指的就是,启动了但还没提交。
低水位:数组里面事务 ID 的最小值记。
高水位:当前系统里面已经创建过的事务 ID 的最大值加 1 。
视图数组和高水位,就组成了当前事务的一致性视图(read-view)。
一个数据版本的 row trx_id,有以下可能:

  1. 在绿色部分,表示这个版本是已提交的事务或者是当前事务自己生成的,这个数据是可见的;
  2. 如果落在红色部分,表示这个版本是由将来启动的事务生成的,是肯定不可见的;
  3. 如果落在黄色部分,那就包括两种情况
    a. 若 row trx_id 在数组中,表示这个版本是由还没提交的事务生成的,不可见;
    b. 若 row trx_id 不在数组中,表示这个版本是已经提交了的事务生成的,可见
    ad

5.不同的事务隔离界别下,查询数据如何工作

在不同隔离级别()下,read committed 总是读最新一份快照数据,而repeatable read 读事务开始时的行数据版本
read_view的生成机制:

  1. read-commited:在每次语句执行的过程中,都关闭read_view, 重新在row_search_for_mysql函数中创建当前的一份read_view。这样就可以根据当前的全局事务链表创建read_view的事务区间,实现read committed隔离级别。
  2. repeatable read:在repeatable read的隔离级别下,创建事务trx结构的时候,就生成了当前的global read view。使用trx_assign_read_view函数创建,一直维持到事务结束,这样就实现了repeatable read隔离级别。

6.一个数据可以保存多少个版本,回滚日志什么时机删除。

  1. 一个数据只保存当前版本,老版本数据通过时间点前数据+回滚日志得到
  2. 当没有未提交事务继续涵盖到时,回滚日志即可删除
    当事务提交之后,undo log并不能立马被删除,而是放入待清理的链表,由purge线程判断是否有其他事务在使用undo段中表的上一个事务之前的版本信息,决定是否可以清理undo log的日志空间。

7.什么是当前读,select 查询如何用当前读。

  1. 读取数据当前最新状态的值,包含未提交事务的修改,插入/更新/删除操作属于当前读,处理的都是当前真实的数据,需要加锁
  2. select 用加锁的方式实现当前读,lock in share mode / for update

8.可重复读级别是否允许出现幻读,InnoDB 可重复读级别是否会出现幻读。

  1. 可重复读级别允许幻读
  2. InnoDB 可重复读级别下没有幻读
  3. 通过间隙锁的方式避免幻读,当InnoDB扫描索引记录的时候,会首先对索引记录加上行锁(Record Lock),再对索引记录两边的间隙加上间隙锁(Gap Lock)。加上间隙锁之后,其他事务就不能在这个间隙修改或者插入记录。Gap Lock在InnoDB的唯一作用就是防止其他事务的插入操作,以此防止幻读的发生。
    Innodb自动使用间隙锁的条件:
    (1)必须在Repeatable Read级别下
    (2)检索条件必须有索引(没有索引的话,mysql会全表扫描,那样会锁定整张表所有的记录,包括不存在的记录,此时其他事务不能修改不能删除不能添加)

9.为什么索引使用 B+树

(a) Innodb存储引擎 默认是 B+Tree索引
(b) MyISAM 存储引擎 默认是Fulltext索引;
©Memory 存储引擎 默认 Hash索引;
B树和B+树的对比:
B 树:B树多用于做文件系统的索引。B树和二叉树、红黑树相比较,子树更多也就是路数越多,子树越多表示数的高度越低,搜索效率越高,当然如果路数太多就可能变成一个有序数组了。所以当然不可能使得路数无限大。正因为文件系统和数据库一般都是存在电脑硬盘上的,如果数据量太大的话不一定能一次性加载到内存中。(一棵树不能一次性加载完怎么查找对吧?)但是B树可以多路存储。也正因为B树的这一个优点,可以在文件查找的时候每次只加载一个节点的内容存入内存来查找。而红黑树在内存中查找非常块,但是如果在数据库和文件系统中,显然B树更优。
B+树: B+树是在B树的基础上进行改造的,他的数据都在叶子节点,同时叶子节点之间还加了指针形成链表。B+树多用于数据库中的索引。因为在数据库中select常常不只是查询一条记录,常常要查询多条记录。比如:按照id的排序的后10条。如果是多条的话,B树需要做中序遍历,可能要跨层访问。而B+树由于所有数据都在叶子结点,不用跨层,同时由于有链表结构,只需要找到首尾,通过链表就能够把所有数据取出来了。

10.常见的索引概念和特性

  1. 聚簇索引、二级索引,描述回表
    聚簇索引:常叫主键索引,比如InnoDb,聚簇索引的叶子节点对应的就是实际的一行数据,由于数据在物理上是一份,所以聚簇索引只能有一个。聚簇索引的索引键就是数据表的主键,如果没有主键会选择一个没有null值的唯一列。
    二级索引:就是常说的普通索引、非聚簇索引,它是与聚簇索引配合使用的,它的B+树的叶子节点存放的是对应数据的主键。查找的时候先获取数据的主键,再根据主键获取实际的数据(这个过程就是回表)
  2. 唯一索引、普通索引,描述性能差异、选用决策参考点
    普通索引(由关键字KEY或INDEX定义的索引)的唯一任务是加快对数据的访问速度。因此,应该只为那些最经常出现在查询条件(WHEREcolumn=)或排序条件(ORDERBYcolumn)中的数据列创建索引。只要有可能,就应该选择一个数据最整齐、最紧凑的数据列(如一个整数类型的数据列)来创建索引
    唯一索引:某个数据列将只包含彼此各不相同的值,一是简化了MySQL对这个索引的管理工作,这个索引也因此而变得更有效率;二是MySQL会在有新记录插入数据表时,自动检查新记录的这个字段的值是否已经在某个记录的这个字段里出现过了;如果是,MySQL将拒绝插入那条新记录。也就是说,唯一索引可以保证数据记录的唯一性。事实上,在许多场合,人们创建唯一索引的目的往往不是为了提高访问速度,而只是为了避免数据出现重复。
    唯一索引和普通索引使用的结构都是B-tree,执行时间复杂度都是O(log n)
  3. 覆盖索引、联合索引、前缀索引、最左前缀原则、索引下推
    覆盖索引:如果一个索引包含了(或覆盖了)满足查询语句中字段与条件的数据就叫做覆盖索引
    联合索引:指对表上的多个列进行索引。
    前缀索引:有时需要索引很长的字符列,它会使索引变大并且变慢。就是对文本的前几个字符(具体是几个字符在建立索引时指定)建立索引,这样建立起来的索引更小,所以查询更快
    最左前缀原则:对于联合索引,只要查询条件与联合索引从左到右部分字段顺序相匹配,该次查询就可以利用联合索引进行加速
    索引下推:在只能利用部分联合索引时,对剩余联合索引的字段(不符和最左匹配原则的字段)进行先判断,先过滤,通过先过滤来减少回表的次数。
    例如有索引(name,age),然后执行SELECT * FORM student WHERE name like ‘高%’ and age=21;
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值