我希望为“一次性”索引实现一个B树(用Java),其中插入几百万个密钥,然后对每个密钥进行少量查询。键是< = 40字节ascii字符串,相关数据总是占用6个字节。选择B树结构是因为我的内存预算不允许我将整个临时索引保留在内存中。
我的问题是关于选择分支因子和在磁盘上存储节点的实际细节。在我看来,有两种方法:
问题是:
我应该在最后提到我知道jdbm3项目,并且正在考虑使用它。在任何情况下都会尝试实现我自己的,既可以作为学习练习,也可以查看特定于案例的优化是否可以产生更好的性能。
编辑:此刻阅读SB-Trees:
答案 0 :(得分:2)
我在这里缺少选项C:
对于所有选项,您都有一些变体:B *或B + Trees(参见维基百科)。
答案 1 :(得分:1)
JDBM BTree已经自我平衡了。它还具有非常快速的碎片整理并解决了上述所有问题。
一个节点可以存储在多个块上。选择分支因子与密钥大小无关。加载单个节点可能需要加载多个块。
没必要。 JDBM3使用映射内存,因此它永远不会从磁盘到内存读取完整块。它创造了一个视图'在块顶部,只读取实际需要的部分数据。因此,它不是读取完整的4KB块,而是只读取2x128字节。这取决于底层OS块大小。
第二种方法通常用于可变长度键吗?还是有一些我错过的完全不同的方法?
我认为你错过了一点,即增加磁盘大小会降低性能,因为必须读取更多数据。并且单个树可以共享两种方法(首先是新插入的节点,在碎片整理后是第二个)。
无论如何,带有映射内存缓冲区的平面文件可能最适合您的问题。由于你有固定的记录大小和几百万条记录。
另外看看leveldb。它有新的Java端口几乎胜过JDBM:
答案 2 :(得分:0)
如果使用某些嵌入式数据库,可以避免这种麻烦。那些已经解决了这些问题,而且已经为你解决了一些问题。
你还写道:"几百万个键" ..." [max] 40字节ascii字符串"和" 6个字节[相关数据]"。这不算数。一个RAM的内存可以让你超过几百万"条目。