数据库篇

219 阅读9分钟

导读

  1. 数据库基础理论
  2. 索引
  3. 事务、分布式事务
  4. 锁、分布式锁
  5. 分库分表
  6. 存储引擎
  7. 隔离级别以及如何实现隔离级别
  8. 常见优化方案及问题解决方案

数据库基础

  • DDL、DML、DCL分别指什么
    DML(data manipulation language)
    它们是SELECT、UPDATE、INSERT、DELETE,就象它的名字一样,这4条命令是用来对数据库里的数据进行操作的语言
    DDL(data definition language)
    DDL比DML要多,主要的命令有CREATE、ALTER、DROP等,DDL主要是用在定义或改变表(TABLE)的结构,数据类型,表之间的链接和约束等初始化工作上,他们大多在建立表时使用
    DCL(Data Control Language)
    是数据库控制功能。是用来设置或更改数据库用户或角色权限的语句,包括(grant,deny,revoke等)语句。在默认状态下,只有sysadmin,dbcreator,db_owner或db_securityadmin等人员才有权力执行DCL explain命令

  • left join,right join,inner join, outer join

  • 数据库的三大范式,五大约束

    1. 三大范式
      1. 第一范式(1NF):数据表中的每一列(每个字段)必须是不可拆分的最小单元,也就是确保每一列的原子性;
      2. 第二范式(2NF):满足1NF后,要求表中的所有列,都必须依赖于主键,而不能有任何一列与主键没有关系,也就是说一个表只描述一件事情;
      3. 第三范式(3NF):必须先满足第二范式(2NF),要求:表中的每一列只与主键直接相关而不是间接相关,(表中的每一列只能依赖于主键);
    2. 五大约束
      • 主键约束(Primary Key Constraint) 唯一性,非空性

      • 唯一约束(Unique Constraint) 唯一性,可以空(但只能有一个)

      • 检查约束(Check Constraint) 对该列数据的范围、格式的限制(如:年龄,性别等)

      • 默认约束(Default Constraint)该列数据的默认值

      • 外键约束(Foreign Key Constraint)需要建立两表间的关系并引用主表的列

      为什么很多公司不允许使用外键?
      外键相当于把数据一致性放到db层来做,为什么不建议放在数据层做,因为应用层机器更便宜,遇到性能瓶颈扩展的成本更低,而且对于互联网公司的应用,并发量大,需求迭代快速,变化也多,放在应用层做更加灵活。

  • 关系型数据库和非关系型数据库区别;

    nosql的简介

引擎

MySQL - 常见的三种存储引擎

索引

【面试题】索引篇

事务

  • 数据库事务ACID(原子性、一致性、隔离性、持久性)

    1. 原子性(A) 所谓的原子性就是说,在整个事务中的所有操作,要么全部完成,要么全部不做,没有中间状态。对于事务在执行中发生错误,所有的操作都会被回滚,整个事务就像从没被执行过一样。

    2. 一致性(C) 事务的执行必须保证系统的一致性,就拿转账为例,A有500元,B有300元,如果在一个事务里A成功转给B50元,那么不管并发多少,不管发生什么,只要事务执行成功了,那么最后A账户一定是450元,B账户一定是350元。

    3. 隔离性(I) 所谓的隔离性就是说,事务与事务之间不会互相影响,一个事务的中间状态不会被其他事务感知。

    4. 持久性(D) 所谓的持久性,就是说一单事务完成了,那么事务对数据所做的变更就完全保存在了数据库中,即使发生停电,系统宕机也是如此。

  • 怎么实现ACID

    • 原子性:依靠redo和undo日志实现
    • 一致性:依靠隔离性来实现
    • 隔离性:隔离级别(锁)和mvcc
    • 持久性:SQL SERVER通过write-ahead transaction log来保证持久性。write-ahead transaction log的意思是,事务中对数据库的改变在写入到数据库之前,首先写入到事务日志中。而事务日志是按照顺序排号的(LSN)。当数据库崩溃或者服务器断点时,重启动SQL SERVER,SQLSERVER首先会检查日志顺序号,将本应对数据库做更改而未做的部分持久化到数据库,从而保证了持久性。
  • 事务的隔离级别(读未提交、读已提交、可重复读、可序列化读)

    • ru:可读未提交,会带来脏读
    • rc:不可读未提交,出现了一次事务范围读出来两个不同的结果
    • rr:在读的时候,不可修改,但是这种情况防不住查询,会产生幻读
    • serializable:串行,序列化
  • 隔离级别的实现原理
    MySQL事务隔离级别的实现原理
    深入理解mysql的事务隔离级别和底层实现原理
    数据库事务系列-MySQL跨行事务模型

  • 悲观锁和乐观锁的原理和应用场景;

    面试必备之乐观锁与悲观锁

  • 共享锁(S)和排他锁(X)

    • 共享锁【S锁】 又称读锁,若事务T对数据对象A加上S锁,则事务T可以读A但不能修改A,其他事务只能再对A加S锁,而不能加X锁,直到T释放A上的S锁。这保证了其他事务可以读A,但在T释放A上的S锁之前不能对A做任何修改。

    • 排他锁【X锁】 又称写锁。若事务T对数据对象A加上X锁,事务T可以读A也可以修改A,其他事务不能再对A加任何锁,直到T释放A上的锁。这保证了其他事务在T释放A上的锁之前不能再读取和修改A。

  • 数据库的锁机制(行锁、表锁、间隙锁)

    参考:行锁、表锁、页锁、乐观锁、悲观锁

日志

  • 一般情况下数据库宕机了如何进行恢复(什么是Write Ahead Log机制,什么是Double Write机制,什么是Check Point,redu、undo日志)

  • 什么是redo和undo日志?
    redu和undo简单介绍
    redo和undo详解

  • binlog、undo日志和redo日志的区别?

    MySQL日志系统:redo log、binlog、undo log 区别与作用

  • 什么是Write Ahead Log机制?
    redo日志应首先持久化在磁盘上,然后事务的操作结果才写入db buffer,(此时,内存中的数据和data file对应的数据不同,我们认为内存中的数据是脏数据),db buffer再选择合适的时机将数据持久化到data file中。这种顺序可以保证在需要故障恢复时恢复最后的修改操作。先持久化日志的策略叫做Write Ahead Log,即预写日志。

  • 什么是double write?

    MySQL 特性:Double Write

  • 什么是Check Point?
    checkpoint是为了定期将db buffer的内容刷新到data file。当遇到内存不足、db buffer已满等情况时,需要将db buffer中的内容/部分内容(特别是脏数据)转储到data file中。在转储时,会记录checkpoint发生的”时刻“。在故障回复时候,只需要redo/undo最近的一次checkpoint之后的操作。

  • MySQL中的MVCC机制是什么意思,根据具体场景,MVCC是否有问题;

    MySQL中一致性非锁定读

    Mvcc机制,线程会读取数据库的undo日志,每次都会读取最新的日志,这样做的有点是无需加锁就可以解决幻读的问题,但是缺点是,有可能读取到的不是最新值。

分库分表

  • 说说分库与分表设计

    • 随着业务量的上升,单表单库的模式已经不能满足要求。当一个表的数据量达到千万级别,就需要考虑分表了。
    • 为什么达到千万级别,就需要考虑分表了,因为索引。每次插入数据,都需要重新计算索引。
    • 分表只能解决对单表的查询插入速度,没法提高库的抗压能力。这时,可以进行垂直拆分,将一些功能比较独立聚合的模块拆分出来。
  • 垂直拆分和水平拆分

    • 垂直拆分 其实是分库,按照功能抽象,将不同模块的数据落在不同的库中
    • 水平拆分 将一份数据,分到多个表中,每一个表是数据的一个分区
  • 分库与分表带来的分布式困境与应对之策

    分库与分表带来的分布式困境与应对之策

    • 表路由:分表的情况下,每次查询或者更新都要带上路由字段,增加了业务复杂度。

    • 分布式事务:分库的情况下,原先一些多表关联查询现在变成了跨库查询。跨表的事务变成了分布式事务。

    • 数据扩容:而且如果需要对系统进行进一步的扩容,将变得非常不方便,需要进行数据迁移。

    • 表关联查询,可以少用表关联语句,通过程序进行组装。

    • 分布式全局id

  • 拓展

    分库分表这样玩,可以永不迁移数据、避免热点

mysql实战

  • limit 20000 加载很慢怎么解决

  • 常见的数据库优化方案,在你的项目中数据库如何进行优化的

    • 长事务和短事务
    • 表的设计遵从三大范式
    • 特别是行程模块的表,因为行程模块大对象比较多,要根据不同的业务类型横向分表,比如景点信息、行程段信息、吃住行、安全须知、行程报价等等。
  • MySQL并发情况下怎么解决(通过事务、隔离级别、锁)

  • 死锁问题的解决

    • 如果出现死锁,可以用SHOW INNODB STATUS命令来确定最后一个死锁产生的原因。返回结果中包括死锁相关事务的详细信息,如引发死锁的SQL语句,事务已经获得的锁,正在等待什么锁,以及被回滚的事务等。据此可以分析死锁产生的原因和改进措施
  • 慢查SQL优化

  • 自增主键用完了会怎么样?

    数据库自增 ID 用完了会咋样?

扩展

spring事务

在Spring篇分析

分布式事务

在分布式篇分析