Database 用B-树优化AVLTree 前提

Database 用B-树优化AVLTree 前提,database,optimization,tree,time-complexity,binary-search,Database,Optimization,Tree,Time Complexity,Binary Search,所以最近我一直在思考一个数据库常见的问题:试图优化数据的插入、搜索、删除和更新。 通常我看到现在的大多数数据库都使用BTree或B+树来解决这个问题,但它们通常用于在磁盘中存储数据,我想处理内存中的数据,所以我考虑使用AVLTree(差别应该是最小的,因为btree的用途与AVLTree相同,但实现不同,效果也不同)。 在继续进行这背后的推理之前,我想更深入地了解我试图解决的问题。 因此,在现代数据库中,数据存储在一个带有主键的表中,主键倾向于被索引(我在索引方面不是很有经验,所以我要说的是我在

所以最近我一直在思考一个数据库常见的问题:试图优化数据的插入、搜索、删除和更新。 通常我看到现在的大多数数据库都使用BTree或B+树来解决这个问题,但它们通常用于在磁盘中存储数据,我想处理内存中的数据,所以我考虑使用AVLTree(差别应该是最小的,因为btree的用途与AVLTree相同,但实现不同,效果也不同)。 在继续进行这背后的推理之前,我想更深入地了解我试图解决的问题。 因此,在现代数据库中,数据存储在一个带有主键的表中,主键倾向于被索引(我在索引方面不是很有经验,所以我要说的是我在这个问题上的基本推理),通常主键是从1开始的一个不断增加的数字(即使现在是一个不好的做法)。 通常使用AVLTree应该足以解决这个问题,因为这个特定的树总是平衡的,并提供O(log2(n))操作,但我想在更深的层次上实现这一点,尝试对它进行优化,甚至超过需要

理论 因此,正如问题的标题所示,我正在尝试优化AVLTree,将其与Btree合并。 基本上,这个新树的每个节点都是由十个元素组成的数组,每个节点也是树中相应的高度,数组中的每个元素都是按升序排列的

插入

当根节点已满时,插入将首先填充根节点的数组。它将生成左、右子节点,其中还包含一个包含10个元素的数组。 每当添加一个新节点时,树会根据左、右子节点向量的第一个键自动平衡节点,同时使用它们的高度(请注意,这实际上是AVLTree的行为方式,但AVLTree只有2个节点,没有向量,只有值)

搜索

搜索元素的工作方式是这样的:从根开始,我们将搜索的
K
值与当前节点数组的第一个和最后一个键进行比较。如果值介于两者之间,我们知道它肯定会在当前节点的数组中,因此我们可以开始使用带有O(log2(n))的二进制搜索在这个由十个元素组成的数组中,如果要搜索的键比第一个键小,我们就从左边开始,如果要搜索的键比第一个键大,我们就从右边开始

删除

与搜索相同,但我们删除了该值

更新

与搜索相同,但我们更新了值

结论
如果我没有错的话,它的复杂性应该是O(log10(log2(10)))它始终是对数的,因此我们不应该关心这种优化,但在我看来,这可能会使树的高度更小,同时提供更快的搜索时间。

由于块设计,B树和B+树确实用于磁盘存储。但没有理由不将它们用作内存数据结构

B树的优点包括在单个节点中使用数组。在一个有限的向量中查找10个条目可能非常快

您关于B树和AVL之间折衷的想法肯定会奏效,但请注意:

  • 为了保持树的平衡,你需要像在AVL中那样执行树的旋转。在B树中,你可以进行重新分布、合并和拆分,但不能进行旋转
  • 与AVL一样,树并不总是完全平衡的
  • 您需要描述当向量已满且需要向其添加值时将执行的操作:节点必须拆分,一半必须作为叶重新注入
  • 您需要描述当向量得到非常低的填充因子(由于删除)时将执行的操作。如果这样,该树可能会退化为AVL树,其中每个向量只有1个值,那么额外的向量开销将使其效率低于真正的AVL树。要使向量的填充因子保持在最小值以上,您无法轻松地对同级节点应用重分发机制,就像在B中所做的那样-树。它可以处理叶节点,但不能处理内部节点。所以这需要澄清
  • 您需要描述更新向量中的值时将执行的操作。当然,您会将其插入其排序位置:但如果它成为该向量中的第一个或最后一个值,这可能会违反左右子项的顺序,因此您可能需要更精确地定义算法
  • 在10个向量中进行二进制搜索可能会有过大的杀伤力:简单的从左到右扫描可能会更快,因为CPU被优化为读取连续内存。这不会影响时间复杂度,因为我们将向量大小限制为10。因此,我们讨论的是最多进行4次比较(根据二进制搜索实现,平均3-4次)或最多10次比较(平均5次)
如果我没有错的话,它的复杂度应该是O(log10(log2(n)),它总是对数的

事实上,如果这是真的,它将是次对数的,即O(loglogn)。但这里有一个错误。向量中的二进制搜索与n无关,而是与10有关。此外,这项工作还包括查找具有该向量的节点。因此,它不是对数的对数,而是对数之和:

O(log10n+log210)=O(logn)

因此,时间复杂度与AVL或B-树的时间复杂度没有区别——前提是该算法在完成时没有遗漏细节,保持在对数复杂度之内

您可能还应该考虑实现纯B树或B+树:这样既可以受益于AVL,也不在两者之间的优点。