在数据库中存储深层目录树

时间:2018-10-15 09:56:42

标签: database mongodb data-structures tree bigdata

我正在使用类似于WinDirStat或voidtools的Everything的桌面应用程序-它映射硬盘驱动器,即在目录树之外创建一个深度嵌套的字典。

然后,桌面应用程序应将目录树存储在某种数据库中,以便可以使用Web应用程序从根目录,深度级别逐级浏览它们。

假设两个应用程序暂时在同一台计算机上本地运行。

想到的问题是,应考虑以下因素,如何构造数据以及应使用哪个数据库? 1)RAM消耗应合理 2)目录可以在Web应用程序中查看的时间应尽可能短

P-S- 我最初的方法是将每个文件系统节点分别序列化为JSON,然后将每个节点插入Mongo,并通过对象引用将它们链接到其子级。这样,Web应用程序可以根据用户需求轻松加载数据。 但是,我担心对Mongo制作这么多(平均一百万个)独立插入内容会花费很多时间;如果我进行批量插入,那意味着我必须将每个批量存储在内存中。

我还考虑将整个树作为一个深度嵌套的JSON进行转储,但是数据太大而无法成为Mongo文档。可以使用GridFS来存储它,但是即使深度节点可能没有兴趣,我仍将整个树加载到Web应用程序中。

1 个答案:

答案 0 :(得分:2)

鉴于您的要求:

  • A)RAM使用率低
  • B)在Mongo中满足文件大小限制
  • C)响应式用户界面

我会考虑以下内容。

使用此示例目录

C:\
C:\X\
C:\X\B\
C:\X\file.txt
C:\Y\
C:\Y\file.pdf
C:\Y\R\
C:\Y\R\file.js

在JSON中,它可能表示为:

{
    "C:" : {
        "X" : {
            "B" : { },
            "file.txt" : "C:\X\file.txt",
        },
        "Y" : {
            "file.pdf" : "C:\Y\file.pdf",
            "R" : {
                "file.js" : "C:\Y\R\file.js",
            }
        }
    }
}

正如您所指出的那样,后者在大型目录结构中无法很好地扩展(我可以直接告诉您,浏览器不会欣赏甚至代表具有数千个文件/文件夹的普通目录的JSON blob)。前者虽然类似于某些实际的文件系统,并且在正确的上下文中是高效的,但要在JSON之间进行转换是很痛苦的。

我的建议是将每个目录分解为一个单独的JSON文档,因为这将解决所有三个问题,但是没有免费的东西,这将增加代码复杂性,每个会话的请求数等。

以上结构可以分为以下文件:

{
    "id" : "CCCCCCCC",
    "type" : "p",
    "name" : "C:",
    "children" : [
        { "name" : "X", "type" : "p", "id" : "XXXXXXXX" },
        { "name" : "Y", "type" : "p", "id" : "YYYYYYYY" }
    ]
}

{
    "id" : "XXXXXXXX",
    "type" : "p",
    "name" : "X",
    "children" : [
        { "name" : "B", "type" : "p", "id" : "BBBBBBBB" },
        { "name" : "file.txt", "type" : "f", "path" : "C:\X\file.txt", "size" : "1024" }
    ]
}

{
    "id" : "YYYYYYYY",
    "type" : "p",
    "name" : "Y",
    "children" : [
        { "name" : "R", "type" : "p", "id" : "RRRRRRRR" },
        { "name" : "file.pdf", "type" : "f", "path" : "C:\Y\file.pdf", "size" : "2048" }
    ]
}

{
    "id" : "BBBBBBBB",
    "type" : "p",
    "name" : "B",
    "children" : [ ]
}

{
    "id" : "RRRRRRRR",
    "type" : "p",
    "name" : "R",
    "children" : [
        { "name" : "file.js", "type" : "f", "path" : "C:\Y\R\file.js", "size" : "2048" }
    ]
}

每个文档仅代表一个文件夹及其直接子文件夹。子文件夹可以使用其ID进行延迟加载,并附加到UI中的父文件夹。实施良好的延迟加载可以将子节点预加载到所需的深度,从而创建响应速度非常快的UI。 RAM使用量极少,因为您的服务器仅需预先处理较小的有效负载。与单个文档方法相比,请求的数量确实增加了很多,但是同样,一些聪明的延迟加载可以将请求聚类并减少总数。

更新1 :在回答之前,我以某种方式忽略了您的倒数第二段,因此,这大概是您所想的。为了解决文档过多的问题,文档中某些级别的群集节点可能是有序的。我现在必须离开,但我会考虑一下。

更新2 :我已经创建了我提到的集群概念的简化版本的要点。它不考虑文件,仅考虑文件夹,也不包括更新文档的代码。希望它能给您一些想法,我将继续为自己的目的对其进行更新。

要点:tree_docs_cluster.js