数据存储 文章目录

前言

一、Mysql

1. 存储引擎===================================

2. 索引=======================================

6、什么是索引?(高频)

3. SQL优化====================================

16、关心过业务系统里面的sql耗时吗?统计过慢查询吗?对慢查询都怎么优化过?(高频)(未写完)

  • 在业务系统中 , 除了使用主键进行的查询 ,其他的我都会在测试库上测试其耗时 ,慢查询的统计主要由运维在做 ,会定期将业务中的慢查询反馈给我们 ;
  • 慢查询的优化首先要搞明白的原因是什么 ?
      1. 是查询条件没有命中索引 ?
      1. 是load了不需要的数据列 ?
      1. 还是数据量太大 ?
  • 所以优化也是针对这三个方向来的 :
      1. 分析语句的执行计划 , 然后获得其使用索引的情况 .之后修改语句或者修改索引 ,使得语句可以尽可能的命中索引 ;
      1. 分析语句 ,看看是否load了额外的数据 ,可能是查询了多余的行并且抛弃掉了,可能是加载了许多结果中并不需要的列 ,对语句进行分析以及重写 ;
      1. 如果是表中的数据量太大导致查询慢 ,可以进行横向或者纵向的分表 ;

4. 事务 =======================================

20、什么是事务?(高频)

  • 由多个操作组成的一个逻辑单元 , 组成这个逻辑单元的多个操作要么同成功 , 要么同失败 ;

21、简单谈一下事务的特性? ACID是什么?可以详细说一下吗?(高频)

  • 事务有四个特性 :
  • A = Atomicity 原子性 :
    • 要么全部成功 , 要么全部失败 , 不可能只执行一部分操作 ;
  • C = Consistency 一致性 :
    • 系统 (数据库)总是从一个一致性的状态转移到另一个一致性的状态 , 不会存在中间状态 ;
  • I = Isolation 隔离性 :
    • 通常来说 , 一个事务在完全提交之前 , 对其他事务是不可见的 ;(有例外情况) ;
  • D = Durability 持久性 :
    • 一旦事务提交 , 哪怕系统崩溃也不会影响到这个事务的结果 ;

22、并发事务带来哪些问题?(高频)

  • 在典型的应用程序中 , 多个事务并发运行 , 经常会操作相同的数据来完成各自的任务(多个用户对同一数据库进行操作) , 并发虽然是必须的 , 但是可能会导致以下问题 :
  • 脏读(Dirty read) :
    • 当一个事务正在访问数据并且对数据进行了修改 , 而这种修改还没有提交到数据库中 , 这时另外一个事务也访问了这个数据 , 然后使用了这个数据 ;
    • 因为这个数据是还没有提交的数据 , 那么另外一个事务读到的这个数据是"脏数据" , 依据"脏数据"所做的操作可能是不正确的 ;
  • 丢失修改 (Lost to modify) :
    • 指在一个事务读取另一个数据时 , 另外一个事务也访问了该数据 , 那么在第一个事务中修改了这个数据后 , 第二个事务也修改了这个数据 ;
    • 这样第一个事务内的修改结果就被丢失 , 因此称为丢失修改 ;
    • 例如 :
      • 事务1读取某表中的数据A=20 , 事务2也读取A=20 , 事务1修改A=A-1 , 事务2也修改A=A-1 ,最终结果A=19 ,事务1的修改被丢失 ;
  • 不可重复读(Unrepeatableread) :
    • 指在一个事务内多次读同一数据 ;
    • 在这个事务还没有结束时 , 另一个事务也访问该数据 ;
    • 那么 ,在第一个事务中的两次读取数据之间 , 由于第二个事务的修改导致第一个事务两次读取的数据时不一样的 情况 , 因此 ,称为不可重复读 ;
  • 幻读(Phantom read) :
    • 幻读与不可重复类似 ;
    • 它发生在一个事务(T1)读取了几行数据 , 接着另一个并发事务(T2) 插入了一些数据时 ;
    • 在随后的查询中 , 第一个事务 就会发现多了一些原本不存在的记录 , 就好像发生了幻觉一样 , 所以称为幻读 ;

23、怎么解决这些问题呢?MySQL的默认隔离级别是?(高频)(未写完)

  • 解决方案:对事务进行隔离
  • MySQL的四种隔离级别如下 :
  • 未提交读(READ UNCOMMITTED)
    • 这个隔离级别下 ,其他事务可以看到本事务没有提交的部分修改。因此会造成脏读的问题(读取到了其他事务未提交的部分 ,而之后该事务进行了回滚) ;
    • 这个级别的性能没有足够大的优势 ,但是又有很多的问题 ,因此很少使用 ;

5. 锁 =========================================

24、MySQL中有哪几种锁?(未写完)

  • 从对数据操作的粒度分 :
    • 表锁 : 操作时 , 会锁定整个表 ;
    • 行锁 : 操作时 , 会锁定当前操作行 ;
    • 页面锁 : 会锁定一部分的数据 ;
  • 从对数据操作的类型分:
    • 读锁(共享锁) : 针对同一份数据 , 多个读操作可以同时进行而不会互相影响 ;
    • 写锁(排他锁) : 当前操作没有完成之前 , 它会阻断其他写锁和读锁 ;

25、MySQL中有哪几种锁?

二、Redis

  • 是一个基于内存的 , key - value 结构化 , 非关系型 数据库 ;

1、简单介绍一下Redis优点和缺点?

  • 优点 :
    • 整个数据库加载在内存当中进行操作 , 定期通过异步操作把数据库数据flush到硬盘上进行保存 ;
    • 因为是纯内存操作 , Redis的性能非常出色 , 每秒可以处理超过10万次读写操作 , 是已知的性能最快的key-value DB ;
    • Redis 支持保存多种数据结构 (string , list , set , hash , sorted set ) , 此外 ,单个value的最大限制是1GB , 而memcached 只能保存 1MB 的数据 ;
  • 缺点 :
    • Redis 的主要缺点是数据库容量受到物理内存的限制 , 不能用作海量数据的高性能读写 , 因此Redis适合的场景主要局限在较小数据量的高性能操作和运算上 ;

2. Redis常见数据结构以及使用场景有哪些?(高频)

  • String : 底层数据结构 : 简单动态字符串() ;
    • 使用场景 : 一般用在需要计数的场景 , 比如用户访问次数 ,热点文章的点赞转发量 ;
  • list : 底层数据结构 : 双向链表 ,压缩列表 ;
    • 使用场景 : 因为列表的元素不但是有序的 ,而且还支持按照索引范围获取元素 ,因此我们可以使用命令lrange key 0 9 分页获取文章列表 ;
  • hash : 底层数据结构 : 哈希表 , 压缩列表 ;
    • 系统中对象数据的存储 ,比如登录后的用户对象信息 ;
  • set : 底层数据结构 : 哈希表 ,整数数组 ;
    • 需要存放的数据不能重复以及需要获取多个数据源交集和并集等场景 ;
  • zset(sorted set) : 底层数据结构 : 跳跃表 ,压缩列表 ;
    • 需要对数据根据某个权重进行排序的场景 ,比如在直播系统中 ,实时排行信息包含直播间在线用户列表 ,各种礼物排行榜 ,弹幕消息等信息 ;

3、系统中为什么要使用缓存?

4、常见的缓存同步方案都有哪些?(高频)

5、Redis有哪些数据删除策略?(高频)

  • 数据删除策略 : Redis中可以对数据设置数据的有效时间 ,数据的有效时间到了以后 ,就需要将数据从内存中删除掉 ,而删除的时候就需要按照指定的规则进行删除 ,这种删除规则就被称之为数据的删除策略 ;
  • Redis中数据的删除策略 ;
    • 定时删除 :
      • 概述 : 在设置某个key的过期时间同时 ,我们创建一个定时器 ,让定时器在该过期时间到来时 ,立即执行对其进行删除的操作 ;
      • 优点 : 定时删除对内存是最好的 ,能够保存内存的key一旦过期就能立即从内存中删除 ;
      • 缺点 : 对CPU最不友好 ,在过期键比较多的时候 ,删除过期键会占用一部分CPU时间 , 对服务器的响应时间和吞吐造成影响 ;
    • 惰性删除
      • 概述:设置该key过期时间后,我们不去管它,当需要该key时,我们在检查其是否过期,如果过期,我们就删掉它,反之返回该key。
      • 优点:对CPU友好,我们只会在使用该键时才会进行过期检查,对于很多用不到的key不用浪费时间进行过期检查。
      • 缺点:对内存不友好,如果一个键已经过期,但是一直没有使用,那么该键就会一直存在内存中,如果数据库中有很多这种使用不到的过期键,这些键便永远不会被删除,内存永远不会释放。
    • 定期删除
      • 概述:每隔一段时间,我们就对一些key进行检查,删除里面过期的key(从一定数量的数据库中取出一定数量的随机键进行检查,并删除其中的过期键)。
      • 优点:可以通过限制删除操作执行的时长和频率来减少删除操作对 CPU 的影响。另外定期删除,也能有效释放过期键占用的内存。
      • 缺点:难以确定删除操作执行的时长和频率。如果执行的太频繁,定期删除策略变得和定时删除策略一样,对CPU不友好。如果执行的太少,那又和惰性删除一样了,过期键占用的内存不会及时得到释放。

6、Redis中有哪些数据淘汰策略?(高频)

  • 数据的淘汰策略:当Redis中的内存不够用时,此时在向Redis中添加新的key,那么Redis就会按照某一种规则将内存中的数据删除掉,这种数据的删除规则被称之为内存的淘汰策略。
    常见的数据淘汰策略:
    • noeviction # 不删除任何数据,内存不足直接报错(默认策略)
      volatile-lru # 挑选最近最久使用的数据淘汰(举例:key1是在3s之前访问的, key2是在9s之前访问的,删除的就是key2)
      volatile-lfu # 挑选最近最少使用数据淘汰 (举例:key1最近5s访问了4次, key2最近5s访问了9次, 删除的就是key1)
      volatile-ttl # 挑选将要过期的数据淘汰
      volatile-random # 任意选择数据淘汰
      allkeys-lru # 挑选最近最少使用的数据淘汰
      allkeys-lfu # 挑选最近使用次数最少的数据淘汰
      allkeys-random # 任意选择数据淘汰,相当于随机
  • 注意:
    • 不带allkeys字样的淘汰策略是随机从Redis中选择指定的数量的key然后按照对应的淘汰策略进行删除,带allkeys是对所有的key按照对应的淘汰策略进行删除。
  • 缓存淘汰策略常见配置项 :
    • maxmemory-policy noeviction # 配置淘汰策略
      maxmemory ?mb # 最大可使用内存,即占用物理内存的比例,默认值为0,表示不限制。生产环境中根据需求设定,通常设置在50%以上。
      maxmemory-samples count # 设置redis需要检查key的个数

7、Redis中数据库默认是多少个db即作用?

8、缓存穿透、缓存击穿、缓存雪崩解决方案?(高频)

  • 加入缓存以后的数据查询流程:
    在这里插入图片描述
  • 缓存穿透 :
    • 概述:指查询一个一定不存在的数据,如果从存储层查不到数据则不写入缓存,这将导致这个不存在的数据每次请求都要到 DB 去查询,可能导致 DB 挂掉。
    • 解决方案:
      • 1、查询返回的数据为空,仍把这个空结果进行缓存,但过期时间会比较短 ;
      • 2、布隆过滤器:将所有可能存在的数据哈希到一个足够大的 bitmap 中,一个一定不存在的数据会被这个 bitmap 拦截掉,从而避免了对DB的查询 ;
  • 缓存击穿 :
    • 概述:对于设置了过期时间的key,缓存在某个时间点过期的时候,恰好这时间点对这个Key有大量的并发请求过来,这些请求发现缓存过期一般都会从后端 DB 加载数据并回设到缓存,这个时候大并发的请求可能会瞬间把 DB 压垮。
    • 解决方案:
      • 1、使用互斥锁:当缓存失效时,不立即去load db,先使用如 Redis 的 setnx 去设置一个互斥锁,当操作成功返回时再进行 load db的操作并回设缓存,否则重试get缓存的方法 ;
      • 2、永远不过期:不要对这个key设置过期时间 ;
  • 缓存雪崩 :
    • 概述:设置缓存时采用了相同的过期时间,导致缓存在某一时刻同时失效,请求全部转发到DB,DB 瞬时压力过重雪崩。与缓存击穿的区别:雪崩是很多key,击穿是某一个key缓存。
    • 解决方案:
      • 将缓存失效时间分散开,比如可以在原有的失效时间基础上增加一个随机值,比如1-5分钟随机,这样每一个缓存的过期时间的重复率就会降低,就很难引发集体失效的事件。

9、什么是布隆过滤器?(高频)

10、Redis数据持久化有哪些方式?各自有什么优缺点?(高频)

  • 在Redis中提供了两种数据持久化的方式:1. RDB , 2. AOF ;
  • RDB(数据快照):定期更新,定期将Redis中的数据生成的快照同步到磁盘等介质上,磁盘上保存的就是Redis的内存快照 ;
    • 优点:数据文件的大小相比于aop较小,使用rdb进行数据恢复速度较快 ;
    • 缺点:比较耗时,存在丢失数据的风险 ;
  • AOF(追加文件):将Redis所执行过的所有指令都记录下来,在下次Redis重启时,只需要执行指令就可以了 ;
    • 优点:数据丢失的风险大大降低了 ;
    • 缺点:数据文件的大小相比于rdb较大,使用aop文件进行数据恢复的时候速度较慢 ;

11、Redis都存在哪些集群方案?

  • 在Redis中提供的集群方案总共有三种:
    • 1、主从复制
      • 保证高可用性
      • 实现故障转移需要手动实现
      • 无法实现海量数据存储
    • 2、哨兵模式
      • 保证高可用性
      • 可以实现自动化的故障转移
      • 无法实现海量数据存储
    • 3、Redis分片集群
      • 保证高可用性
      • 可以实现自动化的故障转移
      • 可以实现海量数据存储

12、说说Redis哈希槽的概念?

  • Redis 集群没有使用一致性 hash,而是引入了哈希槽的概念,Redis 集群有 16384 个哈希槽,每个 key通过 CRC16 校验后对 16384 取模来决定放置哪个槽,集群的每个节点负责一部分 hash 槽。

13、Redis中的管道有什么用?

14、谈谈你对Redis中事务的理解?(高频)

  • 事务是一个原子操作:事务中的命令要么全部被执行,要么全部都不执行。
  • Redis中的事务:Redis事务的本质是一组命令的集合。事务支持一次执行多个命令,一个事务中所有命令都会被序列化。在事务执行过程,会按照顺序串行化执行队列中的命令,其他客户端提交的命令请求不会插入到事务执行命令序列中。
  • 总结说:Redis事务就是一次性、顺序性、排他性的执行一个队列中的一系列命令。Reids中,单条命令式原子性执行的,但事务不保证原子性,且没有回滚。

15. 先更新缓存还是先更新数据库?(面试题)

  • 如果先更新缓存 ,容易造成数据库数据更新失败 ,当缓存的数据过期后 ,则数据全部失效 ;
  • 如果先更新数据库 ,当缓存数据过期后 ,则数据正确 ;
  • 因此 ,应该先更新数据库 , 但是会造成CPU占用 ,影响性能 ,所以可以先更新数据库 ,然后删除缓存 ;

三、MongoDB

1.

总结

Logo

魔乐社区(Modelers.cn) 是一个中立、公益的人工智能社区,提供人工智能工具、模型、数据的托管、展示与应用协同服务,为人工智能开发及爱好者搭建开放的学习交流平台。社区通过理事会方式运作,由全产业链共同建设、共同运营、共同享有,推动国产AI生态繁荣发展。

更多推荐