39

将目录层次结构/树存储在键值数据库中的干净/有效方法是什么(在我的情况下是 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 存储中存储目录结构?

4

4 回答 4

60

您现在使用的方法称为邻接列表模型

在(关系)数据库中存储分层数据的另一种模型是嵌套集模型。它在 SQL 数据库中的实现是众所周知的。另请参阅这篇文章以了解修改后的前序树遍历算法

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

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

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

编辑:此方法称为物化路径

最后,这里比较一下 NOSQL 数据库中分层数据的不同方法

于 2009-12-14T18:52:44.473 回答
1

我没有大量的 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 );
}

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

于 2009-11-02T17:27:19.063 回答
-1

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

例如

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

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

于 2009-12-16T22:32:53.230 回答
-3

做个索引!

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

于 2009-12-16T18:58:53.320 回答