设计人才网站做百度移动网站优
news/
2025/9/23 22:36:41/
文章来源:
设计人才网站,做百度移动网站优,网站域名免费申请,做老师好还是网站编辑好谈到索引#xff0c;大家并不陌生。索引本身是一种数据结构#xff0c;存在的目的主要是为了缩短数据检索的时间#xff0c;最大程度减少磁盘 IO。任何有数据的场景几乎都有索引#xff0c;比如手机通讯录、文件系统(ext4xfsfs)、数据库系统(MySQLOracle)。数据库系统和文件…谈到索引大家并不陌生。索引本身是一种数据结构存在的目的主要是为了缩短数据检索的时间最大程度减少磁盘 IO。任何有数据的场景几乎都有索引比如手机通讯录、文件系统(ext4xfsfs)、数据库系统(MySQLOracle)。数据库系统和文件系统一般都采用 B 树来存储索引信息B 树兼顾写和读的性能最极端时检索复杂度为 O(logN)其中 N 指的是节点数量logN 表示对磁盘 IO 扫描的总次数。MySQL 支持的索引结构有四种B 树R 树HASHFULLTEXT。本篇简单介绍下 B 树下一篇讲 MySQL 常用的两种引擎 MyISAM 和 InnoDB 的 B 树索引实现其余的后面会讲到。一、什么是二叉树再讲什么是 B 树之前先来了看下什么是二叉树。树本身是一种数据存储结构因为类似现实生活中的树而命名。一个看似没有修剪过的树其实这是一棵二叉树每个节点最多有两个子节点。树相关的基础概念拿图 1 这棵树举例说明根节点6 为根节点根节点没有父节点有儿子节点一般叫做 ROOT 节点儿子节点8 和 4 是 6 的儿子节点4 是左儿子8 是右儿子父节点6 是 4 和 8 的父节点父节点是儿子节点的上层节点叶子节点4 和 5 是叶子节点叶子节点指的是除根节点外没有儿子的节点兄弟节点8 和 4 互为兄弟节点因为有共同的父亲 6。1097 三个节点没有兄弟都只有一个儿子层数一棵树的节点层数。图 1 层数为 6高度自下向上遍历从叶子节点遍历到根节点所需要的节点数量。叶子节点 5 到根节点遍历 791086这棵树的高度为 5深度自上而下遍历从根节点到叶子节点遍历所需要的节点数量同样这棵树的深度也是 5高度和深度一般以 0 开始计算当然也有按照从 1 开始计算的平衡因子某节点的左子树与右子树深度的差值一般结果为绝对值。如果任何一个子树不存在按照 0 处理。比如节点 10 的平衡因子就是 3图 1 是一颗非常普通的树非常容易退化为一张链表。如果把图 1 换成如下图 根节点就变为 46 退化为 4 的儿子节点这棵树就退化为一张链表。链表的查找非常慢只能按照节点顺序查找每个节点都遍历一遍时间复杂度为 O(n)无法随机查找。二、平衡二叉树(AVL)那对图 1 进行下改造把数据重新节点重新连接下图 2 如下图 2 可以看到以下特性1. 所有左子树的节点都小于其对应的父节点(456)2. 所有右子树上的节点都大于其对应的父节点(8910)(7)(6)(5)(10)(9)3. 每个节点的平衡因子差值绝对值 14. 每个节点都符合以上三个特征。满足这样条件的树叫平衡二叉树(AVL)树。问那再次查找节点 5需要遍历多少次呢由于数据是按照顺序组织的那查找起来非常快从上往下找7-5只需要在左子树上查找也就是遍历 2 次就找到了 5。假设要找到叶子节点 10只需要在右子树上查找那也最多需要 3 次7-9-10。也就说 AVL 树在查找方面性能很好最坏的情况是找到一个节点需要消耗的次数也就是树的层数 复杂度为 O(logN)如果节点非常多呢假设现在有 31 个节点用 AVL 树表示如图 3图 3 是一棵高度为 4 的 AVL 树有 5 层共 31 个节点橙色是 ROOT 节点蓝色是叶子节点。对 AVL 树的查找来看起来已经很完美了能不能再优化下比如能否把这个节点里存放的 KEY 增加能否减少树的总层数那减少纵深只能从横向来想办法这时候可以考虑用多叉树。三、B 树B 树是一种多叉的 AVL 树。B-Tree 减少了 AVL 数的高度增加了每个节点的 KEY 数量。B 树的特性(m 为阶数结点的孩子个数最大值)1. 树中每个节点最多含有 m 个孩子节点 (m2)2. 除根节点和叶子结点外其他节点的孩子数量 ceil(m / 2)3. 若根节点不是叶子结点最少有两个孩子特殊情况没有孩子的根结点即根结点为叶子结点整棵树只有一个根节点 4. 每个非叶子结点中包含有 n 个关键字信息(nP0K1P1K2P2......KnPn) 其中Ki (i1...n) 为关键字且关键字按顺序升序排序 K(i-1) KiPi 为指向儿子节点的指针且指针 P(i-1) 指向的儿子节点里所有关键字均小于 Ki但都大于 K(i-1)关键字的个数 n 必须满足[ceil(m / 2)-1] n m-1如果一个结点有 n 个关键字那么该结点有 n1 个分支。这 n1 个关键字按照递增顺序排列所有叶子结点都出现在同一层是所有遍历的终点位置按照这个要求把图 3 简单变为一棵 B 树见图 4图 4 是一棵 4 阶 B 树总共有 11 个节点节点数比图 3 少了 20 个层数为 3比图 3 少了两层。实际应用中每个最小单元不是 KEY而一般是按照块(BLOCK)来算。比如磁盘文件系统 EXT4 每块 4KB数据库比如 PostgreSQL 是 8KBMySQL InnoDB 是 16KB MySQL NDB 是 32KB 等。所以再次理清图 4 的 B 树变为图 5图 5 每个节点的基本单元是一个磁盘块(BLOCK默认 4KB)根节点含有一个键值其他节点含有 3 个键值每个磁盘块包含对应的键值与数据。比如现在要读取 KEY 为 31 的记录先找到根节点磁盘块(1)读入内存。(第一次 IO)关键字 31 大于区间(16)根据指针 P2 找到磁盘块 3读入内存(第二次 IO)31 大于区间(202428)根据指针 P4 读取磁盘块 11(第三次 IO)在磁盘块 11 中找到 KEY 为 31 的记录返回结果。这期间有三次磁盘 IO 的读取。可以明确看到B 树相对于 AVL 树减少了树的节点数与树的深度减少了磁盘 IO。看到这里其实有一个问题三次 IO前两次 IO 其实从磁盘读取了不必要的数据因为只用比较 KEY所以非叶子节点对应的 DATA 完全没有必要如果 DATA 很大那完全是浪费内存资源。考虑下能否把非叶子节点的 DATA 拿掉四、B 树B 树是对 B 树的一个小升级。大部分数据库的索引都是基于 B 树存储的。MySQL 的 MyISAM 和 InnoDB 引擎的索引都是基于 B 树存储。B 树最大的几个特点1. 非叶子节点只保留 KEY放弃 DATA2. KEY 和 DATA一起在叶子节点并且保存为一个有序链表(正序反序或者双向)3. B 树的查找与 B 树不同当某个结点的 KEY 与所查的 KEY 相等时并不停止查找而是沿着这个 KEY 左边的指针向下一直查到该关键字所在的叶子结点为止。那对图 5 的 B 树做一个调整变为以下 B 树见图 6图 6 是一棵 6 阶 B 树。不同于图 5非叶子节点不再包含除了主键外的数据数据全部放在叶子节点并且所有叶子节点存放在一个单向链表里当然也可以双向链表。可以看到B 树同时具有平衡多叉树和链表的优点即可兼顾 B 树对范围查找的高效又可兼顾链表随机写入的高效 这也是大部分数据库都用 B 树来存储索引的原因。本篇是为了下一篇介绍 MySQL 的两种常用引擎MyISAM 和 InnoDB 索引结构做了一个铺垫下期见。关于 MySQL 的技术内容你们还有什么想知道的吗赶紧留言告诉小编吧
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/914111.shtml
如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!