1. 数据库事务以及四个特性⭐⭐⭐⭐⭐

  2. 数据库三大范式⭐⭐⭐⭐⭐

  3. 事务的隔离级别⭐⭐⭐⭐⭐

  4. 什么是数据库索引⭐⭐⭐⭐⭐

  5. 索引类型与索引模型⭐⭐⭐⭐⭐

  6. 什么情况下数据库索引会失效⭐⭐⭐⭐⭐

  7. 引起慢查询的常见原因及一些解决方案⭐⭐⭐⭐⭐

  8. 聚簇索引与非聚簇索引⭐⭐⭐⭐⭐

  9. 数据库主键和外键⭐⭐⭐⭐⭐

  10. mysql知道哪些存储引擎,它们的区别⭐⭐⭐⭐⭐

  11. 关系型数据库和非关系型数据库的区别⭐⭐⭐⭐⭐

  12. 数据库垂直与水平拆分怎么做⭐⭐⭐⭐⭐

  13. 什么是内联接、左联接、右联接⭐⭐⭐⭐⭐

  14. 乐观锁与悲观锁⭐⭐⭐⭐⭐

  15. MVCC原理⭐⭐⭐⭐⭐

  16. B树与B+树⭐⭐⭐⭐⭐

=========================================================================================================

  • 本专栏适合于C/C++已经入门的学生或人士,有一定的编程基础。
  • 本专栏适合于互联网C++软件开发、嵌入式软件求职的学生或人士。
  • 本专栏针对面试题答案进行了优化,尽量做到好记、言简意赅。这才是一份面试题总结的正确打开方式。这样才方便背诵
  • 针对于非科班同学,建议学习本人专刊文章《蒋豆芽的秋招打怪之旅》,该专刊文章对每一个知识点进行了详细解析。
  • 如专栏内容有错漏,欢迎在评论区指出或私聊我更改,一起学习,共同进步。
  • 相信大家都有着高尚的灵魂,请尊重我的知识产权,未经允许严禁各类机构和个人转载、传阅本专栏的内容。

=========================================================================================================

  1. 数据库事务以及四个特性⭐⭐⭐⭐⭐

    数据库事务( transaction)是访问并可能操作各种数据项的一个数据库操作序列,这些操作要么全部执行,要么全部不执行,是一个不可分割的工作单位。事务由事务开始与事务结束之间执行的全部数据库操作组成。数据库事务是数据库最小逻辑单元。

    四个特性

    1. 原子性(Atomicity):原子性是指事务包含的所有操作要么全部成功,要么全部失败回滚。失败回滚的操作事务,将不能对事务有任何影响。

    2. 一致性(Consistency):一致性是指事务必须使数据库从一个一致性状态变换到另一个一致性状态,也就是说一个事务执行之前和执行之后都必须处于一致性状态。例如:A和B进行转账操作,A有200块钱,B有300块钱;当A转了100块钱给B之后,他们2个人的总额还是500块钱,不会改变。

    3. 隔离性(Isolation):隔离性是指当多个用户并发访问数据库时,比如同时访问一张表,数据库每一个用户开启的事务,不能被其他事务所做的操作干扰(也就是事务之间的隔离),多个并发事务之间,应当相互隔离。

      例如同时有T1和T2两个并发事务,从T1角度来看,T2要不在T1执行之前就已经结束,要么在T1执行完成后才开始。将多个事务隔离开,每个事务都不能访问到其他事务操作过程中的状态;就好比上锁操作,只有一个事务做完了,另外一个事务才能执行。

    4. 持久性(Durability):持久性是指事务的操作,一旦提交,对于数据库中数据的改变是永久性的,即使数据库发生故障也不能丢失已提交事务所完成的改变。

  2. 数据库三大范式⭐⭐⭐⭐⭐

    1. 第一范式(1NF):数据表中的每一列(每个字段)必须是不可拆分的最小单元,也就是确保每一列的原子性;(比如“姓名与年龄“,我们应该拆分成两个字段:“姓名“、“年龄“。)
    2. 第二范式(2NF):满足1NF后,要求表中的所有列,都必须依赖于同一个主键,而不能有任何一列与主键没有关系,也就是说一个表只描述一件事情;(比如我们主字段是教师的“姓名“,那么字段“年龄“、“工号“、“工资“、“电话“都是与教师相关的,而字段“销售额“跟我们教师没有关系,就要去掉。)
    3. 第三范式(3NF):必须先满足第二范式(2NF),要求:表中的每一列只与主键直接相关而不是间接相关;(如果某一属性依赖于其他非主键属性,而其他非主键属性又依赖于主键,那么这个属性就是间接依赖于主键)
  3. 事务的隔离级别⭐⭐⭐⭐⭐

    事务的隔离性就是指,多个并发的事务同时访问一个数据库时,一个事务不应该被另一个事务所干扰,每个并发的事务间要相互进行隔离。

    1. 读未提交(Read Uncommitted):因为没有行级共享锁,会出现脏读

      脏读就是,比如两个事务都在操作同一个表,A事务修改了C字段的值没有提交该事务;而B事务也在读取C字段的值,就在这时A事务发生了失败回滚,那么C字段的值返回原来的值,所以B事务发生了脏读。整个过程结束,数据库没有发生任何改变,B事务却读到了奇怪的值,这就是脏读。解决办法是行级共享锁。

    2. 读提交(Read Committed):通过行级共享锁,解决了脏读问题,但因为事务没有加锁,导致前后读取数据不一致,即不可重复读

      不可重复读就是,比如两个事务都在操作同一个表,A事务先读取了C字段的值后继续操作下一个字段;而B事务在这个时候修改了C字段的值。A事务再读取C字段的值,发现同一个事务下,竟然前后两次读取不一样,这就很怪异了,这就是不可重复读。解决办法是对事务进行加锁。

    3. 可重复读(Repeated Read):通过事务加锁,解决了不可重复读问题,但因为表没有加锁,会出现幻读的情况,比如多了一行数据。

      幻读就是,比如两个事务都在操作同一个表,A事务先读取了表的行数;而B事务在这个时候为表格新插入了一行数据。A事务再读取表的行数,发现竟多了一行,这就很怪异了,这就是幻读。解决办法是对表进行加锁。

    4. 串行化(Serializable):可解决脏读、不可重复读、幻读问题,通过对表直接加锁的方式,但数据库的读取效率降低

    mysql默认隔离级别为可重复读

  4. 什么是数据库索引⭐⭐⭐⭐⭐

    索引是对数据库表中一列或多列的值进行排序的一种结构,使用索引可快速访问数据库表中的特定信息。与在表中搜索所有的行相比,索引有助于更快地获取信息。唯一、不为空、经常被查询的字段适合建立索引

  5. 索引类型与索引模型⭐⭐⭐⭐⭐

    1. 普通索引:哈希表、红黑树;
    2. 唯一索引:比如设定学号为索引;
    3. 主键索引:设定主键作为索引;
    4. 联合索引:多个字段共同索引;
    5. 全文索引:查找关键字。

    索引模型:哈希表、红黑树、B树、B+树

  6. 什么情况下数据库索引会失效⭐⭐⭐⭐⭐

    1. 如果条件中有or,即使其中有条件带索引也不会使用(要想使用or,又想让索引生效,只能将or条件中的每个列都加上索引)

    2. 不符合最左匹配原则

    3. like查询是以%开头

    4. 如果mysql估计使用全表扫描要比使用索引快,则不使用索引

  7. 引起慢查询的常见原因及一些解决方案⭐⭐⭐⭐⭐

    (1)没有索引或者没有用到索引(这是查询慢最常见的问题,是程序设计的缺陷)

    (2)锁或者死锁(这也是查询慢最常见的问题,是程序设计的缺陷)

    (3)查询语句不好,没有优化

    (4)网络速度慢

    (5)内存不足

    解决方案:

    (1)根据查询条件,建立索引,优化 索引、优化访问方式

    (2)优化锁。可以使用乐观锁、读写锁

    (3)优化查询语句

    (4)提升网络速度

    (5)扩大服务器内存

  8. 聚簇索引与非聚簇索引⭐⭐⭐⭐⭐

    聚簇索引:将数据存储与索引放到了一块,找到索引也就找到了数据

    非聚簇索引:将数据存储于索引分开结构,索引结构的叶子节点指向了数据的对应行

  9. 数据库主键和外键⭐⭐⭐⭐⭐

    1. 主键是能确定一条记录的唯一标识,比如,一条记录包括身份正号,姓名,年龄。

      身份证号是唯一能确定你这个人的,其他都可能有重复,所以,身份证号是主键。

    2. 外键用于与另一张表的关联。是能确定另一张表记录的字段,用于保持数据的一致性。

      比如,A表中的一个字段,是B表的主键,那他就可以是A表的外键。

  10. mysql知道哪些存储引擎,它们的区别⭐⭐⭐⭐⭐

    MyISAM、InnoDB。从MySQL5.5版本之后,MySQL的默认内置存储引擎是InnoDB

    1. InnoDB 支持事务、支持所有隔离级别、行级锁、外键关联、灾难恢复性好、索引和数据是在一起的、用的B+树。不保存行列的信息,使用select需要扫描全表,查找慢些。

    2. MyISAM 不支持事务、不支持行级锁、外键关联,灾难恢复性差、在读写的时候需要锁住整个表,效率低些。但是查找的时候保持行列信息,通过select可以查找相对比较快,索引和数据是分开的、用的B+树。

  11. 关系型数据库和非关系型数据库的区别⭐⭐⭐⭐⭐

    1. 关系型数据库:指采用了关系模型来组织数据的数据库。 关系模型指的就是二维表格模型,而一个关系型数据库就是由二维表及其之间的联系所组成的一个数据组织。比如mysql就是关系型数据库。

    2. 非关系型数据库:指非关系型的,分布式的,且一般不保证遵循ACID原则的数据存储系统。

      非关系型数据库结构

      非关系型数据库以键值对存储,且结构不固定,每一个元组可以有不一样的字段,每个元组可以根据需要增加一些自己的键值对,不局限于固定的结构,可以减少一些时间和空间的开销。

      如典型的Redis就是非关系型数据库。

  12. 数据库垂直与水平拆分怎么做⭐⭐⭐⭐⭐

    垂直拆分:一个数据库由很多表的构成,每个表对应着不同的业务,垂直切分是指按照业务将表进行分类,分布到不同的数据库上面 水平拆分:同一个表拆到不同的数据库中,可以理解为将表中的某些行切分到一个数据库,而另外的某些行又切分到其他的数据库中

  13. 什么是内联接、左联接、右联接⭐⭐⭐⭐⭐

    内联接(Inner Join):匹配2张表中字段相等的记录。 左联接(Left Outer Join):返回左表,并且返回左表与右表字段相等的记录 右联接(Right Outer Join):返回右表,并且返回右表与左表字段相等的记录

  14. 乐观锁与悲观锁⭐⭐⭐⭐⭐

    悲观锁:总是假设最坏的情况,每次去拿数据的时候都认为别人会修改,所以每次在拿数据的时候都会上锁,这样别人想拿这个数据就会阻塞直到它拿到锁。传统的关系型数据库里边就用到了很多这种锁机制,比如行锁,表锁等,读锁,写锁等,都是在做操作之前先上锁。 乐观锁:顾名思义,就是很乐观,每次去拿数据的时候都认为别人不会修改,所以不会上锁,但是在更新的时候会判断一下在此期间别人有没有去更新这个数据,可以使用版本号等机制。乐观锁适用于多读的应用类型,这样可以提高吞吐量,像数据库提供的类似于write_condition机制,其实都是提供的乐观锁。 要明确一下:无论是悲观锁还是乐观锁,都是人们定义出来的概念,可以认为是一种思想。其实不仅仅是关系型数据库系统中有乐观锁和悲观锁的概念,像memcache、hibernate、tair等都有类似的概念。所以,不应该拿乐观锁、悲观锁和其他的数据库锁等进行对比。 实现方式: 悲观锁的实现可以依靠数据库里的锁机制,如排它锁。 乐观锁的实现Compare and Swap(CAS):当多个线程尝试使用CAS同时更新同一个变量时,只有其中一个线程能更新变量的值,而其它线程都失败,失败的线程并不会被挂起,而是被告知这次竞争中失败,并可以再次尝试。 乐观锁每次在执行数据的修改操作时,都会带上一个版本号,一旦版本号和数据的版本号一致就可以执行修改操作并对版本号执行+1操作,否则就执行失败。因为每次操作的版本号都会随之增加,所以不会出现ABA问题,因为版本号只会增加不会减少。除了version以外,还可以使用时间戳,因为时间戳天然具有顺序递增性。 ABA:如果另一个线程修改V值假设原来是A,先修改成B,再修改回成A。当前线程的CAS操作无法分辨当前V值是否发生过变化。关于ABA问题举一个例子:在你非常渴的情况下你发现一个盛满水的杯子,你一饮而尽。之后再给杯子里重新倒满水。然后你离开,当杯子的真正主人回来时看到杯子还是盛满水,他当然不知道是否被人喝完重新倒满。解决这个问题的方案的一个策略是每一次倒水假设有一个自动记录仪记录下,这样主人回来就可以分辨在她离开后是否发生过重新倒满的情况。这也是解决ABA问题目前采用的策略。用悲观锁就可以解决这个问题。

  15. MVCC原理⭐⭐⭐⭐⭐

    MVCC的英文全称是 Multiversion Concurrency Control ,中文意思是多版本并发控制技术。原理是,通过数据行的多个版本管理来实现数据库的并发控制,简单来说就是保存数据的历史版本。可以通过比较版本号决定数据是否显示出来。读取数据的时候不需要加锁可以保证事务的隔离效果MVCC 可以解决什么问题?

    1. 读写之间阻塞的问题,通过 MVCC 可以让读写互相不阻塞,读不相互阻塞,写不阻塞读,这样可以提升数据并发处理能力。
    2. 降低了死锁的概率,这个是因为 MVCC 采用了乐观锁的方式,读取数据时,不需要加锁,写操作,只需要锁定必要的行。
    3. 解决了一致性读的问题,当我们朝向某个数据库在时间点的快照是,只能看到这个时间点之前事务提交更新的结果,不能看到时间点之后事务提交的更新结果。
  16. B树与B+树的区别⭐⭐⭐⭐⭐

    1. B树每个节点都存储数据,所有节点组成这棵树。B+树只有叶子节点存储数据(B+数中有两个头指针:一个指向根节点,另一个指向关键字最小的叶节点),叶子节点包含了这棵树的所有数据,所有的叶子结点使用链表相连,便于区间查找和遍历,所有非叶节点起到索引作用。

    2. B树中叶节点包含的关键字和其他节点包含的关键字是不重复的,B+树的索引项只包含对应子树的最大关键字和指向该子树的指针,不含有该关键字对应记录的存储地址。

    3. B树查找,中途内部节点处可能停止返回,所以B树查找时间复杂度不稳定;B+树中查找,无论查找是否成功,每次都是一条从根节点到叶节点的路径,查找时间复杂度稳定。

    4. B+树的叶子节点通过链表相连,所以B+树范围查找比B树效率高。 B树和B+树的共同优点 考虑磁盘IO的影响,它相对于内存来说是很慢的。数据库索引是存储在磁盘上的,当数据量大时,就不能把整个索引全部加载到内存了,只能逐一加载每一个磁盘页(对应索引树的节点)。所以我们要减少IO次数,对于树来说,IO次数就是树的高度,而“矮胖”就是b树和B+树的特征之一,m的大小取决于磁盘页的大小。

##豆芽点评 全是五颗星,这是数据库的基础,必须掌握,也是高频面试题