title: 面试复习(数据库)
date: 2021-02-23 17:09:12
categories: 学习笔记
tag:
- 面试准备
B 树和 B+ 树
- B 树的特点
- 一个节点上包含至多 $m - 1$ 个值
- 根节点至少有两个孩子
- 非叶子节点如果包含了 $k$ 个值,则其包含了 $k + 1$ 个孩子节点
- 所有叶子节点都位于同一层
- B+ 树的特点
- 所有的非叶子节点不再保存值,而是只保存了中间值
- 所有值保存在叶子节点上
- 所有的叶子节点通过链表按照顺序进行连接
- 为什么数据库会采用 B+ 树而不是 B 树或者 AVL 树
- AVL 的节点访问次数更多,而对于数据库而言,每个节点通常被存储在一个文件中,所以需要读取的文件数量更多,导致效率低
- 在数据库中有时需要进行范围的搜索,此时 B+ 树的链表结构可以快速的找到某个节点的下一个节点位置
联合索引
聚簇索引和非聚簇索引
- 聚簇索引
- 非聚簇索引
- 聚簇索引的优点
- 非聚簇索引的优点
MySQL 锁
- 类型
- 读写锁
- 读锁:可以与其他的读锁共存,但是不可以与写锁共存
- 写锁:不可以与其他任何锁共存
- 悲观锁
- 普通的锁,锁定此行/表/数据库以防止其他操作进行修改,会导致其他事务被阻塞
- 乐观锁
- 通过比较版本号的区别的方法,来确定此数据是否经过修改,如果修改则需要读取最新的值
MyISAM和InnoDB
- 区别
- MyISAM 是 MySQL 之前默认数据库,不支持事务、行级锁和外键,崩溃后无法安全恢复,支持全文索引,强调性能
- InnoDB 是 MySQL 目前的默认数据库,支持了ACID兼容的事务,支持行级锁,不支持全文索引
- 适合范围
- MyISAM 适合读密集场所
- InnoDB 适合写密集场所
数据库联合查询和连接查询
- 联合查询(JOIN)
- 将两张表按照一定规律进行拼接组成结果并返回
SELECT table1.*, table2.* FROM table1 JOIN table2 ON table1.id=table2.id
INNER JOIN
仅当左右两个表同时存在对应的数据时才返回
LEFT JOIN
当左边的表存在则返回
RIGHT JOIN
当右边的表存在则返回
- 连接查询(UNION)
- 将两个或更多查询的结果集组合为单个结果集,查询来自同一个表的相同列
UNION ALL
不做重复性检查
数据库的索引类型
数据库隔离级别
隔离级别 |
脏读(Dirty Read) |
不可重复读(NonRepeatable Read) |
幻读(Phantom Read) |
未提交读(Read uncommitted) |
可能 |
可能 |
可能 |
已提交读(Read committed) |
不可能 |
可能 |
可能 |
可重复读(Repeatable read) |
不可能 |
不可能 |
可能 |
可串行化(Serializable) |
不可能 |
不可能 |
不可能 |
- 隔离级别
- 未提交读:最朴素的数据库形式
- 已提交读:在事务完成之后再更新数据库的值
- 可重复读:每个事务开始前锁定所更新的行
- 可串行化:单一线程,所有事务必须按照顺序进行
- 三种错误
- 脏读:读取到其他事务正在修改过程中的值
- 不可重复读:一个事务中,同一条语句得到的对应行的内容不同
- 幻读:一个事务中,同一条语句得到的数据数量不同
MySQL 的存储引擎
- MySQL 的存储引擎类型
- InnoDB(默认):支持事务处理,支持外键,支持崩溃修复能力和并发控制。如果需要对事务的完整性要求比较高(比如银行),要求实现并发控制(比如售票),那选择InnoDB有很大的优势。如果需要频繁的更新、删除操作的数据库,也可以选择InnoDB,因为支持事务的提交(commit)和回滚(rollback)
- MyISAM(旧版本的 MySQL 默认):插入数据快,空间和内存使用比较低。如果表主要是用于插入新记录和读出记录,那么选择MyISAM能实现处理高效率。如果应用的完整性、并发性要求比较低,也可以使用
- Memory:所有的数据都在内存中,数据的处理速度快,但是安全性不高。如果需要很快的读写速度,对数据的安全性要求较低,可以选择 Memory。它对表的大小有要求,不能建立太大的表。所以,这类数据库只使用在相对较小的数据库表
MySQL 主从复制
- MySQL 主从复制作用
- 实现数据的多处自动备份
- 实现读写分离还能进一步提升数据库的负载性能
- MySQL 主从复制的原理
- 从服务器将日志与主服务器同步,同时重放日志的内容实现数据同步
回表查询
- MySQL 的索引逻辑
- MySQL 会为主键保存一棵聚集索引数树(叶子节点上保存了此节点的所有属性值),而其他的索引则为普通的索引树,普通的索引树进仅保存了主键值而没有保存属性值
- 当需要进行查询且 WHERE 条件不是主键时,需要先通过查询对应的索引,然后通过索引得到主键值,然后再去聚集索引树上搜索对应的主键值,所以需要查询两次索引,效率低
- 覆盖索引
- 如果使用
SELECT
的时候,恰好只需要主键和此搜索值,则可以不搜索聚集索引树,因为仅靠普通索引树即可得到答案
- 为了避免回表,可以通过建议一些可能的联合索引,使得进行
SELECT
的时候不会进行回表操作
连接池
分表
- 水平分表
- 将一个表的记录分割到数个表中,可以减少索引的大小,加快索引
- 垂直分表
- 将部分字段划分至其他的表,部分字段数据量大,进行索引时会带来大量的 IO 负担,进行分表有利于查询效率