MySQL
- 数据库中MySQL是最常用到的,常考的点有:事务
事务
- 什么是transaction?
- 保证数据的一致性
- 事务的特性有哪些?
- 还有一个持久性,即事务结束之后,修改是永久的(落盘)
- 不并发控制的异常情况
- 为了解决上面的问题,提出了四种隔离级别:
- 默认的可重复读,作用就是保证多次查询结果一致,对数据读取加锁
- 具体实现可以参考笔记
高并发
- 问题:如何解决高并发场景下的数据重复问题
- 使用数据库唯一索引(分库分表了可能不行)
- 使用队列异步写入(不着急,一个一个来)
- 使用Redis实现分布式锁
- MySQL还可以使用乐观锁(select for update)和悲观锁(check and set)应对并发场景
数据类型
- 字符串
- 数值
- 日期和时间
引擎
- 区别
索引及优化
- 查找结构演进
- 线性查找,查的慢
- 二分查找,插入慢
- 哈希,占用空间
- 二叉查找树,和哈希一样不适合大规模数据存储(复杂度退化)
- 平衡树(二叉):插入新数据会进行平衡操作,查询快
- 多路查找树:二叉树在节点较多时树还是会很高,于是允许有多个孩子(度)
- 多路平衡查找树(B树):平衡树的改进,既快又不高
- B+树
- B树不能实现范围查询,必须桉树走
- B+树叶子节点通过指针相连,解决了范围查询的问题
- 而且B+树只有叶子结点存数据(指向数据的指针),可以增加树的度
- 观察上图可知,B树由于索引节点也存储记录,而且要保证顺序,树的度就和数据相关,不能随意改变
- B+树的度并不是越大越好
- 因为度是由操作系统对磁盘的管理方式决定的
- 为了更友好的查询和读取数据,也便于系统缓存,磁盘会分块,所以树的度应尽量保证一次查询能获取比较完整的信息
- 问题:什么时候创建索引?
- 根据查询需求创建
- 根据查询需求创建
- 问题:创建索引需要注意什么?
- 最佳实践
- 最佳实践
- 问题:索引什么时候失效?
- 口诀:模糊匹配,类型隐转,最左匹配
- 本质就是如果不能直接与索引比较,就会失效!
- 口诀:模糊匹配,类型隐转,最左匹配
- 什么是聚集索引?
- B+树,叶结点存的如果是指针,就是非聚集(一根针,不扎堆)
- 注意:B+树的索引节点和叶结点不是一回事
- 如果叶结点存了数据,那就是聚集索引,InnoDB的主键索引就是
- MyISAM引擎索引和表是分离的,非聚集
排除慢查询
- 通常是缺少索引,或者索引不合理
SQL编写
- 连接
- 内连:类似求交集(默认)
- 格式:
select * from A inner join B on A.id=B.id;
- 格式:
- 外连:左外和右外,决定主表(可能有空数据)
- 全连接:哪个匹配返回哪个,类似求合集
思考
- 分布式系统如何实现自增ID?
Redis
- 缓存的使用场景;Redis的使用;缓存中的坑
缓存
- 问题:为什么使用缓存?
- 这里说的是内存缓存
- 这里说的是内存缓存
- 两种内存型数据库对比
- 数据类型和使用场景
- 上面五种类型的底层实现方式
- 具体可参考《Redis设计与实现》
- 上面五种类型的底层实现方式
- 跳跃表(skiplist)
持久化
- 有两种方式
- 还是要根据业务特性选择
- 快照方式一般隔一定的时间才会大快照,还是有可能丢失数据
- AOF方式恢复数据的成本较大
事务
- 这里的事务是将请求打包
- 是否支持ACID呢?
- 隔离性:因为是单线程,支持
分布式锁
- 之前是在一个进程内的加锁方式,避免多线程访问出错
- 如果在不同进程间(不同机器)实现锁,可以借助Redis
- 在Redis服务器上,如果某台服务器占用了资源,就为其创建键值对(Hash),并为等待资源的服务器设置超时时间等
缓存
- 缓存使用模式
- 这里主要涉及到数据一致性的问题
- 缓存穿透:缓存中查不到时,到数据库查询
- 缓存击穿:热点数据key过期,大量请求到了后端数据库
- 缓存雪崩:缓存不可用或大量key失效,对策:
思考
- 基于Redis的分布式锁,支持设置超时参数
- 如果Redis单个节点宕机,如何处理?
- 参考