0
点赞
收藏
分享

微信扫一扫

数据库知识点整理(二)

infgrad 2022-04-01 阅读 67
c++面试

数据库索引

1、请你说一说数据库索引

  • 索引(Index)是帮助MySql高效获取数据的数据结构,索引的目的在于提高查询效率,类比字典;实际上索引也是一张表,该表保存了主键与索引字段,并指向实体表的记录,索引列也是要占用空间。
  • 主键索引索引着数据,然而普通索引索引着主键ID值。当你查询用的是where id=x 时,那只需要扫描一遍主键索引,然后拿到相应数据,但是如果是查询的普通索引的话,那么会先扫描一次普通索引,拿到主键值,然后再去扫主键索引,拿到所需要的数据,这个过程叫做回表

2、缺少主键(InnoDB对数据的存储和处理都是基于聚簇索引的)

  • 存在的问题
    (1) 使用不了主键索引,查询会进行全表扫描,影响查询的速度;
    (2) 影响数据插入性能,插入数据需要生成ROW_ID,而生成的ROW_ID是全局共享的,并发会导致锁竞争,影响性能。

  • MySQL如何处理
    (1)如果定义了主键,那么InnoDB会使用主键作为聚簇索引
    (2) 如果没有定义主键,那么会使用第一非空的唯一索引(NOT NULL and UNIQUE INDEX)作为聚簇索引
    (3)如果既没有主键也找不到合适的非空索引,那么InnoDB会自动生成一个不可见的名为ROW_ID的列名为GEN_CLUST_INDEX的聚簇索引,该列是一个6字节的自增数值,随着插入而自增

3、索引在 MySQL 数据库中分三类

(1) B+树索引(InnoDB 存储引擎中最常用的索引)

  • 由来
    • 因为内存的易失性,我们会选择将 user 表中的数据和索引存储在磁盘这种外围设备中。但是和内存相比,从磁盘中读取数据的速度会上百倍千倍甚至万倍,所以,我们应当尽量减少从磁盘中读取数据的次数
    • 另外,从磁盘中读取数据时,都是按照磁盘块来读取的,并不是一条一条的读。如果我们能把尽量多的数据放进磁盘块中,那一次磁盘读取操作就会读取更多数据,那我们查找数据的时间也会大幅度降低。
  • 平衡二叉树的弊端
    • 如果我们用树这种数据结构作为索引的数据结构,那我们每查找一次数据就需要从磁盘中读取一个节点,也就是我们说的一个磁盘块。我们都知道平衡二叉树,可是每个节点只存储一个键值和数据的。那说明什么?说明每个磁盘块仅仅存储一个键值和数据!那如果我们要存储海量的数据呢?可以想象到二叉树的节点将会非常多,高度也会极其高,我们查找数据时也会进行很多次磁盘 IO,我们查找数据的效率将会极低!
    • 为了解决平衡二叉树的这个弊端,我们应该寻找一种单个节点可以存储多个键值和数据的平衡树。也就是我们接下来要说的 B 树。每个节点称为页,页就是我们上面说的磁盘块,在 MySQL 中数据读取的基本单位都是页,所以我们这里叫做页更符合 MySQL 中索引的底层数据结构。
  • B+树
    • 是一种多路搜索树,主要为磁盘或者其他直接存储辅助设备而设计的一种平衡查找树。
    • 在B+树中,每个节点可以有多个孩子,并且按照关键字大小有序排列。
  • B+树 vs. B树
    • 所有记录节点都是按照键值的大小顺序存放在同一层的叶结点中。相比B树,其具有以下几个特点:(1)每个节点上的指针上限是2节点的出度而不是2节点的出度+1;(2)内节点不存储data,只存储key;(3)叶子节点不存储指针

(2) Hash索引

(3) 全文索引

4、 InnoDB一棵B+树可以存放多少行数据?

  • 约2千万行
    • 在计算机中,磁盘存储数据最小单元是扇区,一个扇区的大小是512字节。文件系统中,最小单位是,一个块大小就是4k;InnoDB存储引擎最小储存单元是,一页大小就是16k。
    • 因为B+树叶子存的是数据,内部节点存的是键值+指针。索引组织表通过非叶子节点的二分查找法以及指针确定数据在哪个页中,进而再去数据页中找到需要的数据;假设B+树的高度为2的话,即有一个根结点和若干个叶子结点。这棵B+树的存放总记录数为=根结点指针数单个叶子节点记录行数。如果一行记录的数据大小为1k,那么单个叶子节点可以存的记录数 =16k/1k =16.非叶子节点内存放多少指针呢?我们假设主键ID为bigint类型,长度为8字节,而指针大小在InnoDB源码中设置为6字节,所以就是8+6=14字节,16k/14B =161024B/14B = 1170
    • 一棵高度为2的B+树,能存放1170 * 16=18720条这样的数据记录。同理一棵高度为3的B+树,能存放1170 *1170 *16 =21902400,也就是说,可以存放两千万左右的记录。B+树高度一般为1-3层,已经满足千万级别的数据存储。

5、 为什么索引结构默认使用B+树,而不是B树,Hash哈希,二叉树,红黑树?

(1) Hash哈希

  • 只适合等值查询,不适合范围查询。

(2) 一般二叉树

  • 可能会特殊化为一个链表,相当于全表扫描。

(3) 红黑树

  • 是一种特化的平衡二叉树,MySQL 数据量很大的时候,索引的体积也会很大,内存放不下的而从磁盘读取,树的层次太高的话,读取磁盘的次数就多了。

(4) B-Tree

  • 叶子节点和非叶子节点都保存数据,相同的数据量,B+树更矮壮,也是就说,相同的数据量,B+树数据结构,查询磁盘的次数会更少。

(5)平衡二叉树

  • 平衡二叉树基本都是存储在内存中才会使用的数据结构。
  • 在大规模数据存储的时候,平衡二叉树往往出现由于树的深度过大而造成磁盘IO读写过于频繁,进而导致效率低下的情况。
  • 我们知道要获取磁盘上数据,必须先通过磁盘移动臂移动到数据所在的柱面,然后找到指定盘面,接着旋转盘面找到数据所在的磁道,最后对数据进行读写。
  • 磁盘IO代价主要花费在查找所需的柱面上,树的深度过大会造成磁盘IO频繁读写。根据磁盘查找存取的次数往往由树的高度所决定。
  • 所以,只要我们通过某种较好的树结构减少树的结构尽量减少树的高度,B-树可以有多个子女,从几十到上千,可以降低树的高度,解决了平衡二叉树读取消耗大量内存空间的问题。

6、 B-树和B+树的区别

  • B-树内部节点是保存数据的;而B+树内部节点是不保存数据的,只作索引作用,它的叶子节点才保存数据。
  • B+树相邻的叶子节点之间是通过链表指针连起来的,B-树却不是。
  • 查找过程中,B-树在找到具体的数值以后就结束,而B+树则需要通过索引找到叶子结点中的数据才结束
  • B-树中任何一个关键字出现且只出现在一个结点中,而B+树可以出现多次。
举报

相关推荐

0 条评论