数据库

MySQL 为什么使用 B+ 树来作索引,对比 B 树它的优点和缺点是什么?
优点
B+ 树具有更高的扇出因子,这意味着它们可以在每个节点中存储更多的键。这减少了树的高度并提高了搜索性能。此外,因为B+树仅在其叶子节点中存储键,所以它们可以存储比B树更多的键,B树在内部和叶子节点中都存储键
B+树的另一个优点是它们更适合范围查询。因为所有叶子节点都连接在一起形成一个链表,所以很容易按顺序遍历树并检索某个范围内的所有键。相比之下,B树需要额外的遍历才能找到范围内的所有键
缺点
- 使用B+树需要更多的磁盘空间,因为叶子节点中有额外的指针。此外,由于需要维护叶子节点的链接列表,B+树可能需要更多的CPU时间来执行插入和删除操作
总结
在MySQL中使用B+树而不是B树的决定可能是基于改善搜索性能和增加磁盘空间和CPU使用率之间的权衡
数据库大的事务隔离级别有哪些?各有哪些优缺点?
隔离级别 | 脏读 | 不可重复读 | 幻读 |
---|---|---|---|
Read uncommitted | √ | √ | √ |
Read committed | × | √ | √ |
Repeatable read | × | × | √ |
Serializable | × | × | × |
什么是数据库事务的特性?(简述数据库中的ACID分别是什么)
原子性,一致性,隔离性,持久性
什么情况下会发生死锁,如何解决死锁?
死锁是指两个或多个事务相互等待对方释放资源,从而导致所有事务都无法继续执行的情况。在MySQL中,死锁通常发生在事务中使用了不同的锁定顺序时
解决方法
进行系统的重新启动,代价很大,它意味着在这之前所有的进程已经完成的计算工作都无效,包括参与死锁的进程,以及未参与的进程
撤销进程,剥夺资源。终止参加死锁的进程,收回它们占有的资源,从而解除死锁。
情况一:一次性撤销参与死锁的全部进程,剥夺全部进程
情况二:逐步撤销参与死锁的进程,逐步收回死锁进程占有的资源
一般来说,选择逐步撤销的进程时要按照一定的原则进行,目的是撤销哪些代价最小的进程,比如按进程的优先级确定进程的代价;考虑进程允许是=时的代价和与此进程相关的外部作业的代价等因素
进程回退策略,即让参与死锁的进程回退到没有发生死锁前的某一点处,并由此点处继续执行,以求再次执行时不在发生死锁。
简述乐观锁以及悲观锁的区别以及使用场景
定义
悲观锁(Pessimistic Lock)
每次获取数据的时候,都会担心数据被修改,所以每次获取数据的时候都会进行加锁,确保在自己使用的过程中数据不会被别人修改,使用完成后进行数据解锁。由于数据进行加锁,期间对该数据进行读写的其他线程都会进行等待
乐观锁(Optimistic Lock)
每次获取数据时,都不会担心数据被修改,所以每次获取数据的时候都不会进行加锁,但是在更新数据的时候需要判断该数据是否被别人修改过。如果数据被其他线程修改,则不进行更新,如果数据没有被其他线程修改,则进行更新。由于数据没有进行加锁,期间该数据可以被其他线程进行读写操作
适合场景
悲观锁
比较适合写入操作比较频繁的场景,如果出现大量的读取操作,每次读取的时候都会进行加锁,这样会增加大量的锁的开销,降低了系统的吞吐量
乐观锁
比较适合读取操作比较频繁的场景,如果出现大量的写入操作,数据发生冲突的可能性就会增加,为了保证数据的一致性,应用层需要不断的重新获取数据,这样会增加大量的查询操作,降低了系统的吞吐量
总结
两种锁各有优缺,读取频繁用乐观锁,写入频繁用悲观锁
聚簇索引和非聚簇索引的区别,什么时候使用聚簇索引?
聚簇索引和非聚簇索引是用于提高数据库查询性能的两种索引类型
聚簇索引决定了表中数据的物理顺序。他根据索引列对数据行进行排序和存储。一个表只能有一个聚簇索引
非聚簇索引是数据行之外的独立结构。它包括索引列的副本和指向相应的数据行指针。一个表可以有多个非聚簇索引
聚簇索引最适合在表中频繁查询某个列的一定范围内的值时使用。这是因为数据时根据索引列进行物理排序的,因此检索一定范围内的值更快。而非聚簇索引是数据行之外的一个独立结构,最适合在表中频繁查询使用多个列时使用。在决定使用哪一种时,需要考虑数据修改的频率
注意
在具有频繁插入或更新的表上创建聚簇索引可能会对性能产生负面影响。这是因为每次插入新行或更新现有行时,数据都必须进行物理重组
简述脏读和幻读的发生场景,InnoDB 是如何解决幻读的?
脏读是指一个事务读取了另一个事务未提交的数据,如果另一个事务回滚了操作,那么读取的数据就是无效的。InnoDB通过实现MVCC(多版本并发控制)来避免脏读的发生。MVCC通过在每一行数据后面添加两个隐藏的列来实现,一个是创造时间,一个是过期时间。当一个事务开始时,他会创建一个视图,这个视图包含了当前时间点之前的所有数据。如果一个事务正在修改一行数据,那么这个行的过期时间就会被设置为当前时间,这样其他事务就无法读取到这个行的数据。如果一个事务正在读取一行数据,那么这个行的创建时间必须早于这个事务的开始时间,这样才能保证读取到的数据是有效的
幻读是指一个事务在读取某个范围内的数据时,另一个事务在这个范围内插入和新的数据,导致第一个事务读取到了之前不存在的数据。InnoDB通过实现间隙锁来避免幻读的发生。当一个事务执行SELECT语句时,InnoDB会对查询的范围进行加锁,这样其他事务就无法在这个范围内插入新的数据。如果一个事务要插入新的数据,那么他必须等待其他事务释放锁之后才能执行插入操作
唯一索引与普通索引的区别是什么?使用索引会有哪些优缺点?
唯一索引会限定数据唯一,而普通索引则没有
优点
提高查询效率
索引可以帮助数据库快速定位到符合条件的数据
减少数据扫描
使用索引可以减少数据库扫描的数据量
加速排序
如果查询需要排序,使用索引可以加速排序的过程
缺点
索引会占用磁盘空间
索引会降低写入性能
每次插入,更新或删除数据时,都需要更新索引
索引可能会导致查询变慢
如果索引被错误的使用,或者索引的选择不当
MySQL的索引什么时候会失效?
带有运算
在where子句中使用=,+这些运算符号
使用not in,in
范围运算,会导致索引失效产生全表扫描
like模糊查询,使用%开头的左模糊查询
使用or的时候
因为or是一个并集,如果or条件中有一个不是索引,就会导致索引失效
字段类型与SQL语句类型不匹配时
如果列类型是字符串,则SQL语句中使用到该列的条件数据就必须用引号引用起来,否则会导致索引失效,原因是MySQL会进行隐式的数据类型转换,导致索引失效
使用函数
复合索引违反最左原则时
1
2
3 ## 组合索引a,b,c,需出现a
select * from table where a='' and b='' ## 索引可用
select * from table where b='' and c='' ## 索引不可用使用复合索引(组合索引)时,需要遵循最左前缀原则,即查询条件必须包括复合索引的最左前缀列,才能使用该索引进行查询
最左前缀原则的意义在于,如果查询条件包含复合索引的最左前缀列,那么该索引可以帮助数据库快速定位到符合条件的数据,从而提高查询效率。如果查询条件不包含最左前缀列,那么该索引就无法使用,需要对所有数据进行扫描,这导致查询变慢
简述MySQL的主从同步机制
指将一个MySQL数据库实例(主库)的数据同步到另一个MySQL数据库实例(从库)的过程。主从同步可以实现数据备份,负载均衡,读写分离等操作
原理
主库将更新操作记录在二进制日记(binlog)中,从库连接主库,将主库的binlog复制到从库的中继日志(relay log)中,然后从库读取中继日志,将更新操作应用到从库的数据中。从库可以设置延迟时间,以便在主库出现故障时,从库可以称为新的主库,继续提供服务
步骤
主库接收用户左CRUD操作,写入数据库,更新结果集到binlog中
主从同步时主找从的,从库IO发起请求,主库的主进程看从库 master change 中给的参数是否合法,如果合法主进程交给IO进程执行2操作,否则拒绝处理
主库根据 master 的位置点,从这个位置点的 binlog 日志一直到 binlog 日志最后,将其准备发送给从库
将找到的 binlog 日志发送给从库,并且还会发送新的日志点
从库接收到 binlog 日志,将其写入 relay-log(中继日志)中
从库IO进程再想 master info 保存主库传过来的最后的 binlog 日志的日志位置点
从库IO时循环发起的请求,发了再要,不会管 SQL 读取中继日志的操作。从库 IO 根据新的日志点,向主库发起请求,主库执行 3 4 操作,再发送新的 binlog 给从库,从库再执行5操作
其实第一次向 relay-log 中放数据时,SQL进程就已经知道,SQL进程将 relay-log 中的SQL语句转换成数据,写入从库,从而实现同步
从库 SQL 线程读取中继日志,并不会一次性读完,会把读取到的日志点存放到relay-log.info中
主从同步配置注意
主从库MySQL版本必须一致,否则可能会出现兼容性问题
主从库的字符集和校对规则必须一致,否则可能会出现乱码等问题
主从库的数据表结构必须一致,否则可能会出现同步失败等问题
主从库的数据同步需要保证网络稳定,否则可能会出现同步延迟等问题
主从库的数据同步需要保证主库的写入性能,否则可能会出现主库性能下降等问题
主从复制延迟
指从库的数据更新操作与主库的数据更新操作之间存在一定的时间差,这可能导致从库的数据不一致
网络延迟
主库和从库之间的网络延迟可能会导致从库无法及时获取主库的更新操作
从库负载过高
同上
主库负载过高
如果主库的负载过高,可能会导致主库无法即时将更新操作记录到二进制日志中,从而导致从库无法及时获取更新操作
Redis 如何实现延时队列
可以使用 有序集合 sortedset 来存储任务,我们可以将任务的执行时间作为有序集合的 score,任务大的内容作为有序集合的 member。这样,我们就可以通过 score 的排序来获取最早需要执行的任务
简述 Redis 中如何防止缓存雪崩和缓存击穿
缓存击穿
是指缓存中没有但数据库中有的数据(一般是缓存时间到期),这时由于并发用户特别多,同时读缓存没读到数据,又同时去数据库去取数据,引起数据库压力增大,造成过大压力
解决方法
设置热点数据永不过期
加互斥锁
缓存雪崩
是指缓存中数据大批量到过期时间,而查询数据量巨大,引起数据库压力过大甚至 down 机。和缓存击穿不同的是,缓存击穿指并发查询同一条数据,缓存雪崩是不同数据都过期了,很多数据都查不到从而查询数据库
解决方法
缓存数据的过期时间设置随机,防止同一时间大量数据过期现象发生
如果缓存数据库是分布式部署,将热点数据均匀分布在不同的缓存数据库中
设置热点数据永不过期
简述 Redis 持久化中 rdb 以及 aof 方案的优缺点
RDB 方案
是将 Redis 内存中的数据定期保存到磁盘上,以保证数据的持久化
优点
RDB 方案适合大规模的数据恢复,因为 RDB 文件是一个快照,可以在 Redis 重启时快速的加载数据
RDB 方案对于 Redis 的性能影响较小,因为 RDB 文件是在后台异步生成的,不会影响 Redis 的正常操作
缺点
RDB 方案不够实时,如果 Redis 发生故障,可能会丢失最后一次快照之后的数据
RDB 方案的文件较大,如果数据量较大,可能会占用较多的磁盘空间
AOF 方案
是将 Redis 的操作日志以追加的方式写入到磁盘上,以保证数据的持久化
优点
AOF 方案可以保证数据的实时性,因为每个操作都会被记录到 AOF 文件中
AOF 方案的文件较小,因为只记录了 Redis 的操作日志,而不是整个数据集
缺点
AOF 方案不够适合大规模的数据恢复,因为 AOF 文件是一个操作日志,需要重新执行所有的操作才能恢复数据
AOF 方案对于 Redis 的性能影响较大,因为每个操作都需要写入到 AOF 文件中,会影响 Redis 的正常操作
- 标题: 数据库
- 作者: IntYou
- 创建于: 2023-04-12 11:26:11
- 更新于: 2023-04-20 13:19:35
- 链接: https://intyou.netlify.app/2023/04/12/数据库/
- 版权声明: 本文章采用 CC BY-NC-SA 4.0 进行许可。