Fork me on GitHub

B+树与跳表(SkipList)

为什么 MYSQL 使用 B+树作为 InnoDB 引擎的索引结构?

  <Mysql为什么使用B+树做索引>一文从两个方面介绍了Mysql为什么选择B+Tree作为InnoDB引擎索引的数据结构,本文再做一下简单的总结。

  Mysql数据库的数据被分割为多个页以文件形式储存在硬盘上的。因此我们每次进行数据库查询其实是在进行磁盘 IO,而磁盘 IO 是时间开销较大的操作!数据库在进行索引查找的时候每次访问一个页都是一次磁盘 IO。因此我们需要选择一种能够尽量少做磁盘 IO 的数据结构来构建索引。

  MySQL 默认的存储引擎选择 B+ 树而不是 B 树的原因:

  B 树能够在非叶节点中存储数据,但是这也导致在查询连续数据时可能会带来更多的随机 I/O;而 B+ 树的所有叶节点可以通过指针相互连接,能够减少顺序遍历时产生的额外随机 I/O。B+ 树的扇出率较大,树高较小,因而在进行索引搜索的时候需要进行的 IO 也较其他树的少。B+ 树只有叶节点会存储数据,将树中的每一个叶节点通过指针连接起来就能实现顺序遍历,而遍历数据在关系型数据库中非常常见,所以这么选择是完全没有问题的。 

为什么 Redis 使用跳表 

  跳表

  跳表是一种采用了用空间换时间思想的数据结构。它会随机地将一些节点提升到更高的层次,以创建一种逐层的数据结构,以提高操作的速度。在理论上能够在 O(log(n))时间内完成查找、插入、删除操作。跳表是Redis ZSET类型实现的一种重要数据结构。

  跳表的性质

  (1) 由很多层结构组成,level 是通过一定的概率随机产生的。

  (2) 每一层都是一个有序的链表,默认是升序,也可以根据创建映射时所提供的 Comparator 进行排序,具体取决于使用的构造方法。

  (3) 最底层(Level 1)的链表包含所有元素。

    (4) 如果一个元素出现在 Level i 的链表中,则它在 Level i 之下的链表也都会出现。

  (5) 每个节点包含两个指针,一个指向同一链表中的下一个元素,一个指向下面一层的元素

  跳表的优势

 (1)跳表比 B 树/B+树占用的内存更少

  (2)以链表的形式遍历跳跃表,跳跃表的缓存局部性与其他类型的平衡树相当

  (3)跳表更容易实现、调试等

 思考

  对并发和性能有要求的情况下,如何选择合适的数据结构?

  如果单纯比较性能,跳跃表和红黑树可以说相差不大,但是加上并发的环境就不一样了。如果要更新数据,跳跃表需要更新的部分就比较少,锁的东西也就比较少,所以不同线程争锁的代价就相对少了。而红黑树有个平衡的过程,牵涉到大量的节点,争锁的代价也就相对较高了。性能也就不如前者了。在并发环境下跳表有另外一个优势,红黑树在插入和删除的时候可能需要做一些平衡操作,这样的操作可能会涉及到整个树的其他部分,而跳表的操作显然更加局部性一些,锁需要盯住的节点更少,因此在这样的情况下性能好一些。 

 

posted @ 2022-07-26 09:17  JackpotHan  阅读(2117)  评论(0编辑  收藏  举报