范围查询如何与排序字符串表配合使用?

如何解决范围查询如何与排序字符串表配合使用?

我有点困惑。我找不到有关如何对已排序字符串表执行范围查询的任何信息。

LevelDB 和 RocksDB 支持范围迭代器,允许您在范围之间进行查询,这非常适合 Nosql。我不明白的是它是如何实现的。

表在内存(和磁盘)中排序 - 什么算法或数据结构允许在范围查询中有效地查询排序字符串表?您是否只是遍历条目并依赖充满数据的缓存行?

通常我会在前面放一个前缀树,这给了我键的索引。但我猜排序字符串表会做一些不同的事情,并以某种方式利用排序。

解决方法

LSM 的每一层(除了第一层)在内部都是按键排序的,所以你可以在每一层中保留一个迭代器,并使用指向字典顺序最小元素的迭代器。一个层的文件在磁盘上看起来像这样:

Layer N
---------------------------------------
File1    | File2 | File3 | ... | FileN     <- filename
n:File2  |n:File3|n:File4| ... |           <- next file
a-af     | af-b  | b-f   | ... | w-z       <- key range
---------------------------------------
aaron    | alex  | brian | ... | walter    <- value omitted for brevity,but these are key:value records
abe      | amy   | emily | ... | xena
...      | ...   | ...   | ... | ...
aezz     | azir  | erza  | ... | zoidberg
---------------------------------------

First Layer (either 0 or 1)
---------------------------------------
File1    | File2 |     ...     | FileK
alex     | amy   |     ...     | andy
ben      | chad  |     ...     | dick
...      | ...   |     ...     | ...
xena     | yen   |     ...     | zane
---------------------------------------
...

假设您正在寻找范围 ag-d(独占)中的所有内容。 “范围扫描”只是找到第一个匹配元素,然后迭代层的文件。所以你发现 File2 是第一个包含任何匹配元素的,并扫描到第一个以 'ag' 开头的元素。您遍历 File2,然后查看 File2 (n:File3) 的下一个文件。您检查它包含的键范围并发现它包含您感兴趣的范围中的更多元素,因此您对其进行迭代,直到找到以 'd' 开头的第一个条目。你在每一层都做同样的事情,除了第一层。第一层的文件没有相互排序,但它们是内部排序的,所以你可以为每个文件保留一个迭代器。您还为当前的 memtables 保留了一个(内存数据,仅保存在日志中)。

这永远不会变得太昂贵,因为第一层通常在一个小的恒定阈值上压缩。由于每一层中的文件都是排序的,并且文件也是按键在内部排序的,因此您可以只推进最小的迭代器,直到所有迭代器都用完为止。除了初始搜索之外,每一步都必须查看固定数量的迭代器(假设是一种简单的方法),因此是 O(1)。大多数 LSM 使用块缓存,因此顺序读取通常会在大部分时间命中缓存。

最后但并非最不重要的一点,请注意,这主要是一个概念性的解释,因为大多数实现都有一些额外的技巧,可以使这些事情更高效。无论如何,当您进行主要压缩时,您必须知道哪些数据包含在哪些文件范围中,即将第 N 层合并到第 N + 1 层。甚至文件级操作也可能看起来完全不同:例如,RocksDB 维护一个在每个文件的开头带有键偏移量的粗索引,以避免扫描文件中通常大得多的键/值对部分。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其他元素将获得点击?
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。)
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbcDriver发生异常。为什么?
这是用Java进行XML解析的最佳库。
Java的PriorityQueue的内置迭代器不会以任何特定顺序遍历数据结构。为什么?
如何在Java中聆听按键时移动图像。
Java“Program to an interface”。这是什么意思?
Java在半透明框架/面板/组件上重新绘画。
Java“ Class.forName()”和“ Class.forName()。newInstance()”之间有什么区别?
在此环境中不提供编译器。也许是在JRE而不是JDK上运行?
Java用相同的方法在一个类中实现两个接口。哪种接口方法被覆盖?
Java 什么是Runtime.getRuntime()。totalMemory()和freeMemory()?
java.library.path中的java.lang.UnsatisfiedLinkError否*****。dll
JavaFX“位置是必需的。” 即使在同一包装中
Java 导入两个具有相同名称的类。怎么处理?
Java 是否应该在HttpServletResponse.getOutputStream()/。getWriter()上调用.close()?
Java RegEx元字符(。)和普通点?