索引与字典不相似吗?如果您有密钥,可以立即访问它吗?
显然索引有时会存储为B-Trees ......为什么会这样?
答案 0 :(得分:8)
字典不是隐式排序的,B-Tree
是。
B-Tree
索引可用于远程访问,如下所示:
WHERE col1 BETWEEN value1 AND value2
或订购,如下:
ORDER BY col1
您无法立即访问B-Tree
索引中的页面:您需要遍历编号以对数方式增加的子页面。
某些数据库也支持字典类型索引,即HASH
索引,在这种情况下搜索时间是不变的。但是这些索引不能用于远程访问或排序。
答案 1 :(得分:4)
数据库索引通常(几乎总是)存储为B树。并且所有平衡树结构都具有用于搜索的O(log n)复杂度。
'Dictionary'是'抽象数据类型'(ADT),即它是一个不指定实现的功能描述。一些字典可以使用Hashtable进行O(1)查找,其他字典可以使用树并实现O(log n)。
数据库使用B-trees(超过任何其他类型的树)的主要原因是B树是自平衡的并且非常“浅”(需要很少的磁盘I / O)
答案 2 :(得分:3)
您可以使用密钥立即访问的唯一数据结构之一是向量,对于大量数据,当您开始插入和删除元素时,该向量将变得低效。它还需要连续的内存分配。
哈希可以很有效但需要更多空间并最终会发生冲突。
B树在搜索性能和空间之间有很好的平衡。
答案 3 :(得分:2)
如果您的唯一查询是等式测试,那么它的真实字典是一个不错的选择,因为它们将在摊销的O(1)时间内进行查找。但是,如果您想扩展查询以涉及范围检查,例如(select * from students where age > 10
),那么您的字典突然完全失去了优势。这就是基于树的索引的来源。使用基于树的索引,您可以执行对数时间的等式和范围检查。
天真树结构存在一个问题。它们变得不平衡,这意味着在向索引添加某些值之后,树结构变得不平衡(例如长行)并且查找开始再次花费O(N)时间。这可以通过平衡树来解决。 B-Tree就是这样一种方法,它也利用了能够执行大块I / O的系统,因此最适合数据库。
答案 4 :(得分:1)
hashindex(例如,在mysql和postgres中)具有用于搜索的恒定复杂度(O(1))。
CREATE INDEX ... USING HASH
答案 5 :(得分:1)
如果您为数组预先分配 N 条目,并且哈希是此的密钥,则可以实现O(1)
N 值。
但是如果你存储了超过N个条目,那么就会发生碰撞。因此,对于数组中的每个键,您都有一个值列表。所以它不再是O(1)
了。扫描列表本身将是O(m)
,其中m是平均碰撞次数。
Example with hash = n mod 3
0 --> [0,a] [3,b] ...
1 --> [1,a] [4,b] [7,b] ...
2 --> [2,a] [5,b] ...
在某个时间点,与使用O(log n)
查找时间的其他结构相比,您花费更多时间遍历潜在密钥的值列表会变得更糟糕,其中n是条目的总数。 / p>
你当然可以选择 N ,以至于数组/哈希比B-Tree更快。但是阵列具有固定的预分配大小。因此,如果 N = 1000且存储3个值,则会浪费数组中的997个插槽。
所以它基本上是一个性能空间权衡。对于一小组值,array
和散列非常好。对于大量值,B-Tree
效率最高。
答案 6 :(得分:1)
哈希是最快的查找数据结构,但有一些问题:
a)未分类 b)无论散列有多好,都会发生冲突,这在大量数据时会出现问题 c)在哈希索引文件中查找哈希值需要很长时间,因此大多数时间哈希仅对内存(RAM)数据有意义 - 这使得它们不适合数据库 - 大多数时候都不适合所有数据库RAM中的数据
排序树解决了这些问题,特别是b-tree操作可以使用文件有效地实现。唯一的缺点是它们作为哈希结构的查找时间较慢。
在所有情况下,没有数据结构是完美的,取决于估计的数据大小以及如何使用它,一个更好。