在MySQL中,索引类型是b树,访问b树中的元素的是对数摊销时间O(log(n))
。
另一方面,访问哈希表中的元素位于O(1)
。
为什么不使用哈希表而不是b-tree来访问数据库中的数据?
答案 0 :(得分:85)
您只能通过哈希表中的主键访问元素。
这比使用树算法( O(1)
而不是log(n)
)更快,但您无法选择范围( x
和{{之间的所有内容1}} 的)。
树算法在y
中支持此功能,而哈希索引可以导致全表扫描Log(n)
。
哈希索引的常量开销通常也更大(,这不是theta表示法的因素,但它仍然存在)。
树算法通常也更容易维护,随着数据,规模等而增长。
散列索引使用预定义的散列大小,因此您最终会得到存储对象的“桶”。这些对象再次循环,以便在此分区中找到正确的对象。
因此,如果您的尺寸较小,则对于小尺寸元素会产生大量开销,因此大尺寸会导致进一步扫描。
今天的哈希表算法通常会缩放,但缩放可能效率低下。
确实存在可扩展的散列算法。不要问我这是怎么回事 - 对我来说这也是一个谜。 AFAIK是从可扩展复制发展而来的,其中重新散列并不容易。
其名为 RUSH - R 明显 U nder S 可销售 H 灰化,这些算法因此被称为RUSH算法。
但是,与散列大小相比,索引可能超出容许大小,并且需要重新构建整个索引。通常这不是问题,但对于巨大的庞大数据库,这可能需要数天时间。
树算法的权衡很小,它们几乎适用于所有用例,因此是默认的。
但是,如果您有一个非常精确的用例并且您确切地知道需要什么,那么您可以利用散列索引。
答案 1 :(得分:56)
实际上,根据以下link,MySQL似乎使用散列表或b树这两种索引。
使用b-tree和哈希表之间的区别在于前者允许你在使用=,>,> =,<,&lt的表达式中使用列比较 ; =,或BETWEEN运算符,而后者仅使用进行相等比较,使用=或< =>运算符。
答案 2 :(得分:13)
哈希表的时间复杂度仅对于足够大小的哈希表是恒定的(需要有足够的桶来保存数据)。事先不知道数据库表的大小,因此必须立即对表进行重新分析,以便从哈希表中获得最佳性能。重组也很昂贵。
答案 3 :(得分:5)
我认为Hashmaps也不会扩展,并且在需要重新整理整个地图时可能会很昂贵。
答案 4 :(得分:1)
除了这里的好答案之外,这里还有一些关于如何构建数据库的观点。
首先,健壮哈希表通常使用分桶系统完成,例如用于实现 JavaScript“对象”(即哈希表)的 Quadratic Probing。您可以在 JavaScript here 中看到分桶哈希表的实现。
您会注意到,在此实现中,进行的处理比 O(1)
表示法所看到的要多得多。首先,您通过散列函数运行它,该函数迭代输入字符串的长度,并且每次迭代有 5 个以上的计算步骤。但请注意,这些是快速计算步骤,因为它们都是在寄存器中完成的,而不是在 RAM 中。接下来,您使用该哈希值来获取 bucket。我不确定有多少个桶,或者一个桶有多长,但这个桶是一个数组或链表。因此,然后您遍历存储桶项目,并将每个项目与您要为其获取值的输入键进行比较。这又是一个字符串比较。因此,我很可能估计即使是一个简单的字符串也至少需要 100 个计算步骤才能从哈希表中获取它。所有这些字符串比较加起来。
此外,桶可能是半空的,这会占用大量无用的空间。最后,当哈希表的占用率达到一定大小时,它的大小必须加倍!它必须重新处理和重新计算一切。这可能会导致 UI 应用程序出现明显故障。
另一方面,B+树是一种更紧凑的数据结构。您仍在进行字符串比较,但您只是跳过 MAX 我会说树中的 20 个链接(就深度而言),然后扫描最后一个树节点中的子节点以找到完全匹配。
从这个意义上说,我认为实际上 B+树或 B 树将与哈希表相当,尤其是幼稚的实现。两个系统都可以优化和微调,我仍然认为它们会接近相等。只有测试会告诉你。但是树具有更紧凑的内存优势。因此,在考虑了很长时间并权衡了方程式的各个方面之后,我将选择 B+树作为快速查找项目的理想解决方案。
答案 5 :(得分:1)
ENGINE=MEMORY
(很少使用)和内部用于“哈希连接”。OPTIMIZE
),但很少值得付出努力。PRIMARY KEY
排序的 BTree 中。辅助键也存储在 BTree 中,但按辅助键列排序。那么只有叶节点中的其他信息是 PRIMARY KEY
值。因此,辅助键查找需要两次 BTree 查找(除非所有必需的列都在辅助 + 主列中——这称为“覆盖”)。最后我说 Big-O 可能很有趣,但实现的细节增加了复杂性。以及任意大表的性能。
答案 6 :(得分:0)
Pick DB / OS基于哈希,并且运行良好。如今,有了更多的内存来支持有效的稀疏哈希表,并使用冗余哈希来支持适度的范围查询,我想说哈希可能仍然占有一席之地(有些人宁愿使用其他形式的非范围相似性匹配,例如通配符和正则表达式)。我们还建议进行复制,以在内存层次结构具有较大速度差异时使冲突链保持连续。
答案 7 :(得分:0)
另一件事也可能影响选择:哈希表可以很好地将一个键映射到一个单一的值。但是,在一个键映射到大量元素(对于表的单列非常常见)的情况下,您很容易失去 O(1) 行为,具体取决于它的处理方式。 BTrees 没有这个问题并且可以很好地处理大量重复条目。