一、什么是数据库索引

1、索引的概念

  • 1.简单来说,数据库索引是数据库的数据结构。索引是对数据库库表中的一列或多列的值进行排序的一种结构,使用索引可以快速访问数据库表中的特定信息。
  • 2.索引的一个主要目的是加快检索表的数据的方法,亦即能协助信息搜索者尽快的找到符合限制条件的记录ID的辅助数据结构。
  • 3.索引是对数据库表中一个或多个列(例如,employee 表的姓名 (name) 列)的值进行排序的结构。

2、索引的优缺点

  • 优点:

    • 1.加快数据的搜索速度;(在没有索引的情况下,数据库会遍历全部数据后选择符合条件的返回)
    • 2.加快表与表之间的连接速度;
    • 3.在信息检索的过程中,若使用分组及排序子句进行时,通过建立索引能够有效减少检索过程中所需的分组和排序时间,提高检索效率。
  • 缺点:

    • 1.在我们建立数据库的时候,需要花费的时间去建立和维护索引,而且随着数据量的增加,需要维护它的时间也会增加。
    • 2.在创建索引的时候会占用存储空间,索引文件越大,占用的空间越多。
    • 3.在我们需要修改表中的数据时,索引还需要进行动态的维护,所以对数据库的维护带来了一定的麻烦。由于索引底层大多是B+树等平衡多叉树,为了维护平衡,增删的时间效率很差。

3、索引的类型

  • 普通索引:最基本的索引,没有任何限制。
    唯一索引:索引列的值必须唯一,可以有空值。
    主键索引:一种特殊的唯一索引,不允许有空值。
    全文索引:它的作用是搜索数据表中的字段是不是包含我们搜索的关键字,就像搜索引擎中的模糊查询。
    组合索引:为了更多的提高mysql效率可建立组合索引,遵循“最左前缀”原则。

4、主键和外键

  • 主键:关系型数据库中的一条记录有若干个属性,若其中一个属性组能够唯一标识一条记录,该属性组就可以成为一个主键。
  • 外键用于与另一张表的关联。是能确定另一张表记录的字段,用于保持数据的一致性。
    比如,A表中的一个字段,是B表的主键,那他就可以是A表的外键。

4、索引的低层数据结构

  • 数据库的索引是使用B+树来实现的。
    B+树是一种特殊的平衡多路树,是B树的优化改进版本,它把所有的数据都存放在叶节点上,中间节点保存的是索引。这样一来相对于B树来说,减少了数据对中间节点的空间占用,使得中间节点可以存放更多的指针,使得树变得更矮,深度更小,从而减少查询的磁盘IO次数,提高查询效率。另一个是由于叶节点之间有指针连接,所以可以进行范围查询,方便区间访问。
    而红黑树是二叉的,它的深度相对B+树来说更大,更大的深度意味着查找次数更多,更频繁的磁盘IO,所以红黑树更适合在内存中进行查找。

  • B树,B+树等。这两种都是平衡多叉树。B树的结点保存索引和关键字,B+树的非叶子结点保存索引,叶子节点保存关键字的有序链表。

  • B树和B+树的区别

    • 关键字的数量不同;B+树中分支结点有m个关键字,其叶子结点也有m个,其关键字只是起到了一个索引的作用,但是B树虽然也有m个子结点,但是其只拥有m-1个关键字。
    • 存储的位置不同;B+树中的数据都存储在叶子结点上,也就是其所有叶子结点的数据组合起来就是完整的数据,但是B树的数据存储在每一个结点中,并不仅仅存储在叶子结点上。
    • 分支结点的构造不同:B+树的分支结点仅仅存储着关键字信息和儿子的指针(这里的指针指的是磁盘块的偏移量),也就是说内部结点仅仅包含着索引信息。
    • 查询不同;B树在找到具体的数值以后,则结束,而B+树则需要通过索引找到叶子结点中的数据才结束,也就是说B+树的搜索过程中走了一条从根结点到叶子结点的路径。
  • B+树优点:由于B+树的数据都存储在叶子结点中,分支结点均为索引,方便扫库,只需要扫一遍叶子结点即可,但是B树因为其分支结点同样存储着数据,我们要找到具体的数据,需要进行一次中序遍历按序来扫,所以B+树更加适合在区间查询的情况,所以通常B+树用于数据库索引,而B树则常用于文件索引。

5、联合索引的最左前缀原则

  • 假如我们对a b c三个字段建立了联合索引,在联合索引中,从最左边的字段开始,任何连续的索引都能匹配上,当遇到范围查询的时候停止。比如对于联合索引index(a,b,c),能匹配a,ab,abc三组索引。并且对查询时字段的顺序没有限制,也就是a,b,c; b,a,c; c,a,b; c,b,a都可以匹配。

6、数据库三大范式

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

7、聚集索引和非聚集索引

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

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

8、索引的设计原则

  • 1、索引并非越多越好:避免对经常更新的表创建过多的索引,索引中的列要尽可能的小;经常要查询的字段应该创建索引,但是要避免添加不必要的字段。
  • 2、 数据量小的表最好不要使用索引:在条件表达式中经常用到的不同值较多的列上建立索引,在不同值少的列上不要建立索引
  • 3、当唯一性是某种数据本身的特性时,建立唯一索引
  • 4、在频繁进行排序或者分组的列上建立索引

9、MVCC

  • MVCC的英文全称是 Multiversion Concurrency Control ,中文意思是多版本并发控制技术。原理是,通过数据行的多个版本管理来实现数据库的并发控制,简单来说就是保存数据的历史版本。可以通过比较版本号决定数据是否显示出来。读取数据的时候不需要加锁可以保证事务的隔离效果。
  • MVCC 可以解决什么问题?
    读写之间阻塞的问题,通过 MVCC 可以让读写互相不阻塞,读不相互阻塞,写不阻塞读,这样可以提升数据并发处理能力。
    降低了死锁的概率,这个是因为 MVCC 采用了乐观锁的方式,读取数据时,不需要加锁,写操作,只需要锁定必要的行。
    解决了一致性读的问题,当我们朝向某个数据库在时间点的快照是,只能看到这个时间点之前事务提交更新的结果,不能看到时间点之后事务提交的更新结果。

10、MySQL的优化

  • 高频访问:

    • 分表分库:将数据库进行水平拆分,减少表的长度;
    • 增加缓存:在web和DB之间加上一层缓存层;
    • 增加数据库的索引:在合适的字段加上索引,解决高频访问的问题
  • 并发优化:

    • 主从读写分离:只在主服务器上写,从服务器上读
    • 负载均衡集群:通过集群或者分布式的方式解决并发压力

11、MYSQL数据库引擎介绍,innodb和myisam的特点与区别

InnoDB : InnoDB是mysql的默认引擎,支持事务和外键,支持容灾恢复。适合更新频繁和多并发的表 行级锁
MyISAM : 插入和查询速度比较高,支持大文件,但是不支持事务,适合在web和数据仓库场景下使用 表级锁
MEMORY : memory将表中的数据保存在内存里,适合数据比较小而且频繁访问的场景
CSV
blackhole

二、数据库面经

参考:https://zhuanlan.zhihu.com/p/128546246
https://blog.csdn.net/ssh520mxd/article/details/107174586