将目录层次结构存储在键值数据存储区中
什么是干净/有效的方法来存储目录层次结构/树在键值数据库(在我的情况下,MongoDB,但其中任何)?
例如一个树形结构
- Cars + Audi + BMW - M5 + Ford - Color + Red - Apple - Cherry + Purple - Funny
我现在使用的方法,每个对象链接到它的父
{ dir: "red" parent-dir: "color" }
这使得插入和重新排列树的任何一个方面(例如,如果我想将Red和所有它的子节点移动到Cars目录)非常有效/快速。
但是,当我想让recursion的给定目录的所有子目录和他们的子目录时,这个方法很糟糕。 为了使其高效parsing,我可以有一个结构,例如
{ dir: "red" children: "audi, bmw, ford" } { dir: "bmw" children: "m5" }
但是如果我想修改树,需要触摸和修改一大堆对象。
有什么其他的方法来存储在KV商店的目录结构?
您目前使用的方法称为邻接列表模型 。
在(关系)数据库中存储分层数据的另一个模型是嵌套集合模型 。 它在SQL数据库中的实现是众所周知的 。 另请参阅本文中关于修改的预定义树遍历algorithm 。
一个非常简单的方法:您可以为每个对象存储path – 在NOSQL数据库中查询树应该很容易:
{ path: "Color", ... } { path: "Color.Red", ... } { path: "Color.Red.Apple", ... } { path: "Color.Red.Cherry", ... }
当节点将被删除或重命名时,必须更新一些path。 但总的来说,这种方法看起来很有希望。 你只需要保留一个特殊的字符作为分隔符。 存储空间的开销应该可以忽略不计。
编辑:这种方法被称为物化path
最后,这里是NOSQL数据库中分层数据的不同方法的比较 。
我没有大量的NOSQL经验,所以这不是一个明确的答案,但这是我的方法:
我可能会使用你的第一种方法,你有:
{ dir: 'dir_name', parent_dir: 'parent_dir_name' }
然后设置map-reduce来快速查询目录的子目录。 MongoDB的map-reducefunction仍然只在开发分支中可用,我还没有使用它,但是在CouchDB中(我假设在MongoDB中做了一些修改),你可以这样做:
map: function(doc) { emit( doc.parent_dir, doc.dir ); } reduce: function(key, values) { return( values ); }
哪个会给你每个父目录的子目录列表。
我build议存储一堆到数据项的ID。 我认为这是最好的计划。 如果你需要大量的东西,任何堆元素都可能成为另一堆的索引。
例如
{ "id:xxx", "id:yyy", "sub-heap-id:zzz"....}
如果不明确,发表评论,我会解释更多,当我回家。