蟒蛇:从磁盘

问题描述:

快速查找字典我有形式的大辞典(1mil的键):蟒蛇:从磁盘

{ 
    key1: { 
     file1: [number_list1], 
     file7: [number_list2], 
     file10: [number_list3], 
     ... 
    } 
    key2: { 
     file1: [number_list4], 
     file5: [number_list5], 
     file2: [number_list6], 
     ...    
    } 
    ... 
    ... 
} 

由于种种约束,构建它后,我无法保持它在内存中,有将其以腌渍形式转储到磁盘上。但是,我仍然希望从磁盘快速查找任何一个密钥。 我的想法是把大字典分成更小的块(0.5-1MB的球场)。这需要额外的键:块映射,但允许我在查找过程中只加载必要的块。我想出了以下算法:

def split_to_pages(self, big_dict): 
    page_buffer = defaultdict(lambda: defaultdict(list)) 
    page_size = 0 
    page_number = 0 
    symbol2page = {} 
    for symbol, files in big_dict.items(): 
     page_buffer[symbol] = files 
     symbol2page[symbol] = page_number 
     page_size += deep_sizeof_bytes(files) 
     if page_size > max_page_size: 
      save_page_to_file(page_number, page_buffer) 
      page_buffer.clear() 
      page_size = 0 
      page_number += 1 
    if page_size > 0: 
     save_page_to_file(page_number, page_buffer) 

此解决方案执行良好的静态字典。然而,由于它代表了一个动态的实体,因此很有可能在操作过程中将新密钥引入或从字典中删除。为了反映这种变化,我的解决方案需要从头开始划分整个字典。有没有更好的方法来处理这种情况?我有一种感觉,这是一个我不知道的常见问题,已经提出了更好的解决方案。

编辑:

我试过shelve,约0.5秒键查找时间为一个小型的数据库(2K键),速度很慢。我上面介绍的半分页调度算法大约是0.01s。 sqlite3做了1mil密钥表的0.4s查找时间,我怀疑mongo会更快。我的用例开销太多了。我想我会继续我自己的分区数据库实现。

+2

我猜这是数据库被发明的原因? – Grimmy

+0

同意。您可以尝试使用'redis','mongoDB'或其他一些NoSQL存储。 – bpscott

+0

你可以给'tinydb'一个镜头。不知道它可以处理多少数据。 – Grimmy

这是一个常见问题。我想你应该看看数据库像mongodb