在键值数据存储中存储目录层次结构

Posted

技术标签:

【中文标题】在键值数据存储中存储目录层次结构【英文标题】:Storing Directory Hierarchy in a Key-Value Data store 【发布时间】:2010-12-09 19:06:44 【问题描述】:

将目录层次结构/树存储在键值数据库(在我的情况下是 MongoDB,但其中任何一个)中的干净/高效方法是什么?

例如树形结构

- Cars 
   + Audi 
   + BMW
      - M5
   + Ford
- Color
   + Red
      - Apple
      - Cherry
   + Purple
- Funny

我现在使用的方法,每个对象都链接到它的父对象

 
  dir: "red"
  parent-dir: "color"

这使得插入和重新排序树的任何方面都非常高效/快速(例如,如果我想将 Red 及其所有子项移动到 Cars 目录)。

但是当我想递归地访问给定目录的所有子目录及其子目录时,这种方法很糟糕。为了提高解析效率,我可以有一个结构,例如

 
  dir: "red"
  children: "audi, bmw, ford"


 
  dir: "bmw"
  children: "m5"

但是如果我想修改树,需要触摸和修改一大堆对象。

还有其他方法可以在 KV 存储中存储目录结构吗?

【问题讨论】:

真的这个问题更笼统......在KV数据存储中存储任何分层数据的最佳方式是什么...... +1:我不知道这个 KV 趋势。我学到了一些新东西,谢谢。 PS:对于像我这样的人来说,这是一个体面的 KV 说明:readwriteweb.com/enterprise/2009/02/… MonogoDB 不是键值存储! It's a document oriented database database 【参考方案1】:

你现在使用的方法叫adjacency list model。

在(关系)数据库中存储分层数据的另一种模型是nested set model。它的implementation in SQL databases is well known。另见this article for the modified preorder tree traversal algorithm。

一个非常简单的方法:您可以为每个对象存储一个路径 - 使用这些路径应该很容易在 NOSQL 数据库中查询树:

 path: "Color", ... 
 path: "Color.Red", ... 
 path: "Color.Red.Apple", ... 
 path: "Color.Red.Cherry", ... 

当节点将被删除或重命名时,必须更新一些路径。但总的来说,这种方法看起来很有希望。您只需要保留一个特殊字符作为分隔符。存储空间开销应该可以忽略不计。

编辑:这个方法被称为materialized path

最后,这里是a comparison of different methods for hierarchical data in NOSQL databases。

【讨论】:

MongoDB 文档中有一篇非常好的文章,介绍了存储树的可能性:mongodb.org/display/DOCS/Trees+in+MongoDB @Frunsi 为什么不使用 Zookeeper 来存储这些信息,因为它内置了对层次结构的支持 @Itachi:为什么?为什么不?这就像我要问你为什么在开车时不总是使用儿童安全座椅一样离题。 树结构的工作链接:docs.mongodb.com/manual/applications/…【参考方案2】:

我没有大量的 NOSQL 经验,所以这不是一个明确的答案,但我会这样做:

我可能会使用你的第一种方法,你有:


  dir: 'dir_name',
  parent_dir: 'parent_dir_name'

然后设置一个map-reduce来快速查询一个目录的孩子。 MongoDB 的 map-reduce 功能仍然只在开发分支中可用,我还没有使用它,但是在 CouchDB 中(我假设在 MongoDB 中进行了一些修改)你可以执行以下操作:

map:
function(doc) 
  emit( doc.parent_dir, doc.dir );


reduce:
function(key, values) 
  return( values );

这将为您提供每个父目录的子目录列表。

【讨论】:

【参考方案3】:

我建议将堆存储到数据项的 id 中。 我认为这是最好的计划。如果你需要很多很多东西,任何堆元素都可以是另一个堆的索引。

例如

"id:xxx", "id:yyy", "sub-heap-id:zzz"....

如果不清楚,请发表评论,我回家后会解释更多。

【讨论】:

【参考方案4】:

做一个索引!

http://www.mongodb.org/display/DOCS/Indexes

【讨论】:

以上是关于在键值数据存储中存储目录层次结构的主要内容,如果未能解决你的问题,请参考以下文章

SharedPreferences 存储

13.1 存储选项

Android - 不同存储选项的生命周期

无法在键值存储中设置未定义的属性

键值存储的优势是啥?

NoSQL数据库进阶实战 2,NoSQL数据存储模式