数据库-八股文

  1. 索引的设计原则
  2. 1.类型不多的列没必要建索引,占空间,效果还不好
    2.由于索引也是要占空间的,而且索引建立完毕以后,之后的写入操作都需要更新索引,因此,索引越多对写入操作越不友好,索引的数量要控制
    3.索引建立的列,不能是全模糊和前模糊查询的那种情况[全模糊与前模糊都不走索引],尽量建立在精确匹配的场景
    4.索引建立的列,尽量不要建立在text类型上
    
  3. 索引的基本原理-√
  4. 1.索引对应列进行排序
    2.将排序结果建立倒排表
    3.将数据地址链拼接到倒排表上
    4.查询的时候,拿到倒排表,查询到数据地址链,最后取到需要的数据
    
  5. 事务的基本特性和隔离级别-※
  6. 基本特性
    ACID: atom consistent isolation duration
    原子性:每个事务的执行应当是原子性的,要么都执行,要么都不执行
    一致性:数据库总是从一致性的状态变化到另外一种一致性的状态,所有数据应当具有一致的状态,不存在矛盾;即无论何时,数据都应当满足本身的约束条件    
    隔离性:事务之间应当是隔离的,不会互相影响
    持久性:事务一旦提交,就持久化到数据库里面了
    
    隔离级别
    1.读未提交 脏读,一个事务A没有执行完,另一个事务B读到了A的中间处理结果
    2.读已提交 不可重复读,一个事务A没有执行完,事务B读到的数据为C,事务A执行完毕,事务B读到的数据为D
    3.可重复读 ,利用多版本并发控制,事务A写操作的数据版本与事务B读操作的数据版本不一致,从而保证两个事务读写操作是独立的
    4.串行,每个操作都加锁,保证串行执行,但效率很低,一般不用
    
  7. 什么是MVCC
  8. MVCC multi version concurrent control 多版本并发控制
    
    简而言之就是 每个数据都有若干版本,读写分离,操作的是不同版本的数据
    
    读已提交:每次读 都生成一个readView
    可重复读:每次读都复用同一个readView
    
  9. 简述MyISAM和InnoDB的区别
  10. 存储
    1.MyISAM 中,索引和数据分别是一份文件,是非聚集索引的方式存储的
    2.InnoDB 中,索引和数据共用一份文件,是聚集索引的方式存储的
    
    事务:
    1.MyISAM 中,不支持事务
    2.InnoDB 中,支持事务
    
    悲观锁
    1.MyISAM 中,仅支持表锁
    2.InnoDB 中,支持行锁、表锁、间歇锁、临键锁
    
    约束:
    1.MyISAM 不支持外键约束
    2.InnoDB 支持外键约束
    
  11. Explain语句中各个字段分别表示什么?-※
  12. 索引覆盖是什么?
  13. 查询索引的时候,所有目标结果列就已经包含在索引里面了,因此,就没有必要再去查找原表了,从而提高了查询效率
    
  14. 最左前缀原则是什么?-※
  15. 查询SQL的时候,如果利用到了联合索引,那么使用索引的时候,必须带上第一个索引,否则索引会失效
    
  16. InnoDB是如何实现事务的?
  17. InnoDB的事务实现主要依赖于buffer pool ,redo log ,undo log
    以update为例
    1.首先定位到需要更新的数据页,并缓存到buffer pool
    2.执行update操作,更新buffer pool中的数据,即更新内存数据
    3.针对当次操作,生成redolog对象以及undolog日志
    4.如果事务提交的话,将redolog对象进行持久化,并通过其他机制将buffer pool中的数据持久化到磁盘
    5.如果事务放弃的话,通过undolog可以将数据进行回滚
    
  18. 为什么mysql底层要用B+树
  19. 与二叉查找树、平衡二叉查找树、红黑树相比,B树的高度更低,可以明显减少磁盘IO的次数,从而提高查询性能
    选B+树 不选B
    原因
    1.B+ 非叶子节点不存放数据,因此,能寻址的范围会更大
    2.B+ 叶子节点之间有类似双向链表的结构,范围查询的时候,根结点找到一个端点就可以遍历了,而B树需要重新根结点去查询
    3.B+ 叶子节点之间有类似双向链表的结构,全表扫描的时候,效率会比B树更高,B树需要遍历全树
    
  20. Mysql的锁有哪些?如何理解?-√
  21. 1.共享锁 排他锁
    共享锁:其他线程可以读 但是不能写,也不能加排他锁,可以加共享锁
    排他锁:其他线程不可读不可写,也不能继续加锁
    
    2.行锁 表锁
    行锁:锁定一行
    表锁:锁定一张表
    
    3.乐观锁、悲观锁
    乐观锁:不是真正上锁 而是通过数据多版本控制的方式实现上锁,乐观认为 自己上锁以后 不会有其他线程同时访问修改该数据,最后判断一下上锁的版本号是不是最新的版本,如果不是最新版本就放弃操作
    悲观锁:例如行锁、表锁
    
  22. mysql自增ID用完以后会怎样?
  23. MySQL中update是行锁还是表锁?
  24. 1.当where条件里面有索引,并只更新一条数据,那么就是行锁
    2.当where条件里面有索引区间,那么会加间歇锁
    2.当where条件里面没有索引,就是表锁
    
  25. MySQL事务底层原理?
  26. 事务的基本特性是ACID
    mysql事务的底层原理就是如何保证ACID基本特性
    
    A:atom,原子性,全部执行或者全部不执行,正常情况下,当所有命令执行完毕以后,才执行提交;非常情况,mysql中有设计一张表-UNDO-LOG,出现问题以后,数据库通过读取这个日志表,执行反向操作,即可进行回滚,相当于全部不执行。
    
    C:consistent,一致性,数据库设计了主键约束和外键约束等一系列约束条件来尽量保证逻辑一致性
    
    I:isolation,隔离性,数据库总共分为四种隔离级别,脏读、不可重复读、可重复读以及串行化,MVCC多版本并发控制机制规避了脏读、不可重复读的问题,同时数据库也提供了行锁和表锁处理幻读的问题[LBCC,lock based concurrency control,基于当前版本读写]。
    
    D:duration,持久化,即事务执行完成以后,数据改动就会持久化到磁盘上,为了确保数据能正常持久化到磁盘上,mysql设计了一个文件REDO-LOG,修改的值与操作变更都会保存到这个文件,如果宕机的话,将这个文件重新持久化即可。
    
  27. 如何优化SQL?
  28. select * from tb_special_app
    left join dic_dddd
    where network_app='123456'
    having xxx
    group by aaa
    order by bbbb
    
    1.查询是否包含索引
    2.结果列是否有冗余
    3.子查询尽量不要超过2层
    4.尽量用表关联代替子查询
    5.尽量将筛选多的条件放前面,比如,先筛选掉很多数据以后再进行表关联之类的
    6.排序子段尽量是索引字段
    7.SQL实在没有优化空间的情况下,就考虑分库分表,考虑优化整体查询逻辑
    
    
  29. 为什么有些公司禁用存储过程
  30. 禁用存储过程,主要考虑维护和管理上的问题
    1.不方便维护,逻辑都在数据库,要升级的时候,既要升级代码,还要升级数据库里面的逻辑
    2.很多公司,是无法直接接触到生产环境的数据库的
    3.很多公司的数据库都是由DBA维护的,如果数据库和代码两边都和业务关联,工作职能有重复冲突,同时带来维护工作问题
    
    
  31. limit 100 0000,10 很慢,如何优化?
  32. 核心思想就是通过索引和降低数据量 无论是单独索引还是主键索引
    1.如果能建自增ID为主键索引,就将翻页信息,通过主键来实现
    2.如果已有主键,就新建索引,甚至增加一列ID
    3.先用条件查询筛选出部分数据,降低数据库遍历翻页的数量[例如上次查询最大ID为600,这次应该就是ID>600 limit 10]
    4.还能将翻页数据缓存到Redis里面,每次SQL都查询 10W 条
    
  33. MySQL的索引 优缺点?
  34. mysql是通过B+树结构存储对应的数据以及索引
    
    优点:
    1.B+树结构,树的高度有限,有效减少磁盘IO次数
    2.B+树的叶子节点互相之间,是通过双向链表连接的,因此,范围查询的时候,找到一个边界就可以直接遍历,不需要重新从根节点开始定位[全表扫描的时候可以直接遍历,无需遍历整棵树]
    
    缺点:
    1.由于索引的存在,数据的维护也需要反映到索引上,增加的写操作的成本,数据量过大或者索引过多,都会增大写操作的成本
    2.如果数据类别不多,例如性别字段,建索引反而会降低性能[因为类别不多不可能是主键,因此,一定是非聚簇索引,但是类别不多,非聚簇索引并不能排除掉很多数据,相反还会额外带来一次IO]
    
  35. 数据量多大的时候 需要分库分表?
  36. 开放式命题,并不能单独从数据量出发考虑
    
    数据量:如果数据量很大了,例如单表百万条记录,就可以开始考虑分库分表了[例如单服务器上的单表]
    业务:当业务本身有领域拆分的时候,需要对数据进行分离的时候,也需要考虑分库分表
    性能:当单个数据库无法满足业务的需要的时候,例如,数据库无法支撑常规的并发请求时,就要考虑分库分表
    
    
  37. 数据库字段为啥建议设置not null?
  38. 省事:
    1.数据库   不需要针对null单独判断,性能有所提高
    2.开发人员 不需要针对null单独判断,代码更简洁、清晰
    
    约束 规范:
    1.如果字段设置为not null,则更容易确保数据的一致性与完整性
    
  39. binlog和redolog有什么区别?
  40. 使用场景不同:
    1.binlog:数据备份、数据恢复以及主从同步
    2.redolog:未提交事务回滚,已提交事务持久化
    
    内容不同:
    1.binlog:逻辑变动
    2.redolog:物理变动
    
    记录时间不同:
    1.binlog:语句级别的记录,执行SQL的时候记录
    2.redolog:事务级别的记录,事务完成以后记录
    
    
  41. MVCC过程中会加锁吗
  42. 结论:
    1.读写、读读不会
    2.写写会
    
    因为MVCC过程用的是 写时复制 来保证隔离
    读操作与写操作针对的数据版本不是一样的版本,从而解决了脏读与不可重复读的问题
    
    写操作与写操作之间,每个写操作都会加悲观锁,从而使得事务ID与数据的版本ID一致才可以完成写操作。
    
posted @ 2023-07-07 22:45  356a  阅读(64)  评论(0编辑  收藏  举报