树结构的数据模型(文件系统):文档模型与图模型

时间:2015-10-18 22:59:35

标签: mongodb neo4j orientdb graph-databases arangodb

我正在评估一个nosql解决方案,用于实现类似于结构的文件系统,其中包含数百万个项目,其中主要功能必须是:

  • 速度发现"父母"或者"直接孩子"或者"子树孩子"由n项属性过滤的项目,页面结果按项目属性排序。

有了这个要求我将问题分解为2个任务:

  1. 为搜索子项/子树子项建立递归项结构
  2. 为项目属性搜索项目结构建模
  3. 现在,nosql schema free的强大功能是为每个文件存储不同属性的一个很好的功能,这对第2点很有用。

    我对第1点关于使用文档数据库(示例mongodb)以及单个项目集合和物化路径设计模式,或使用带有2个集合的图形数据库(示例arangodb)的利弊进行了一些疑问:用于数据(文档集合)的项目,以及用于父子关系(边缘集合)和items遍历函数的items父母。

    根据我的要求使用图形数据库的性能有哪些优势?

    图形遍历比物化路径过滤器更有效地完成我的任务?

    如果是的话,你能解释一下为什么吗?

    由于

2 个答案:

答案 0 :(得分:8)

图形数据库肯定是文件系统等层次结构的绝佳选择。特别是Neo4j,你可以有一个架构,如:

(:Folder)-[:IN_FOLDER]->(:Folder)
(:File)-[:IN_FOLDER]->(:Folder)

查找文件或文件夹就像以下Cypher一样简单:

MATCH (file:File {path: '/dir/file'})
RETURN file

直接在文件夹下找到所有文件/文件夹:

MATCH (folder:Folder {path: '/dir'})<-[:IN_FOLDER]-(file_or_folder)
RETURN file_or_folder

如果您想以递归方式查找所有文件/文件夹,可以执行以下操作:

MATCH (folder:Folder {path: '/dir'})<-[:IN_FOLDER*1..5]-(file_or_folder)
RETURN file_or_folder

1..5调整您正在搜索的深度(从1到5级)。

对于所有这些,您需要pathFolder标签的File属性索引。当然,根据您的使用情况,您不需要这样做。

在这种情况下Neo4j可以如此快得多的原因是因为一旦你在磁盘上找到一个节点,就可以通过几次文件访问来遍历关系,而不是为每一跳搜索整个表或索引。我建议您查看免费书籍Graph Databases by O'Reilly,了解有关Neo4j内部的详细信息。

答案 1 :(得分:7)

多模型数据库可以更好地服务于您的用例,该数据库既是文档存储又是图形数据库。使用这样的数据存储,您可以将所有项目作为顶点放在一个集合中,并将层次结构的关系作为边缘放在单独的集合中。此外,您可以存储每个项目的路径并具有已排序的索引,如果常量时间很重要,则可以使用路径属性上的哈希索引。

你会得到

  1. O(1)(常量时间)按路径查找项目(使用哈希索引)
  2. O(1)通过图形邻居或通过(截断的)路径查找来查找父级
  3. 使用图邻居
  4. 在时间O(n)中找到所有n个直接孩子
  5. 通过排序索引中的范围查找以与结果中项目数成比例的方式查找完整子树
  6. 通过添加更多二级索引来接近任意快速项目访问
  7. 1-4。是最好的,因为复杂性不能比结果集的大小好。

    让我更详细地解释一下性能论点:

    案例1.和2.两种方法都很好,因为您只需要一个结果,您可以直接访问。无论你是否使用哈希索引或让排序索引足够,都可能很重要。

    案例3(直接子节点)使用图形数据库更快,因为它“找到所有直接邻居”作为一个非常快速的原语。如果您依赖于物化路径和已排序的索引,则无法使用范围查询来获取直接子项,因此它会更慢。

    情况4.(整个子树)使用已排序索引的物化路径和范围查询更快,因为它可以只发出(如果需要,使用迭代器)一个完整的范围。图形数据库必须执行图遍历,这将涉及服务器上的(临时)数据突变以进行枚举。

    多模型数据库的优势在于,您可以结合您在单个数据存储中建议的两种方法(3.和4.)的优势。

    此类数据库的一种可能性是ArangoDB database

    免责声明:我是主要开发者之一。