2015-10-18 90 views
3

我评估的NoSQL解决方案,实现一个文件系统,如结构,拥有数百万的项目,其中主要功能必须是:数据模型:文档模型VS图模型

  • 通过n项属性筛选的项目的速度查找“父母”或“直接孩子”或“子树孩子”,页面结果按项目属性排序。有此需求

我在2任务分割问题:

  1. 模型递归项目结构搜索孩子的/子树童车
  2. 模型的项目结构,搜索过的项目属性

现在nosql模式免费的力量是一个很好的功能,为每个文件存储不同的属性,这对第2点很好。

对于使用文档数据库(示例mongodb)的优点/缺点,使用单个项目集合和物化路径设计模式,或使用具有2个集合的图形数据库(示例arangodb),我对第1点有一些怀疑:用于数据(文档集合)的项目以及用于父子关系(边集合)和图形遍历功能的项目父项。

使用图形数据库为我的需求提供性能优势?

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

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

谢谢

回答

7

图形数据库肯定是像文件系统这样的层次结构的一个很好的选择。说到具体的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调整您正在搜索的深度(从一级到五级)。

对于所有这些,您希望FolderFile标签的path属性的索引。当然,你不需要这样做,这取决于你的用例。

Neo4j在这种情况下可以如此之快的原因是因为一旦在磁盘上找到节点,只需几次文件访问即可遍历关系,而不是为每个跃点搜索整个表或索引。我建议查看免费书Graph Databases by O'Reilly了解Neo4j的内部细节。

+0

如果您有任何关于Neo4j的其他问题,可以在这里找到一个活跃的Slack组:http://neo4j.com/blog/public-neo4j-users-slack-group/ –

7

您的用例最好由多模型数据库提供,它既是文档存储又是图形数据库。有了这样的数据存储,您可以将所有项目作为顶点放入一个集合中,并将层次关系作为单独集合中的边缘。此外,您可以将路径与每个项目一起存储并且具有排序索引,并且如果常量时间很重要,则会在路径属性上使用散列索引。

你会得到

  1. O(1)(恒定时间)查找通过其路径的项目(使用散列索引)
  2. O(1)查找的父母或者由图邻居或通过(截短的)路径查找
  3. 找到所有n个直接的孩子在时间O(n)使用图邻居
  4. 找到一个完整的子树的范围查找在排序索引的时间成正比的项目数结果
  5. 通过添加进一步的二级索引获得任意快速物品访问附近

1.-4。是最好的,因为复杂性不能比结果集的大小更好。

让我多一点详细讲解了性能参数:

例1和2是用好两种方法,因为你只需要一个结果,你可以直接访问。无论您是使用散列索引还是让已排序的索引都足够可能很少。

案例3(直接孩子)在图形数据库中速度更快,因为它将“查找所有直接邻居”看作是一个非常快速的基元。如果您依赖物化路径和已排序的索引,则无法使用范围查询获得直接子项,因此速度会变慢。

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

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

这样的数据库的一种可能性是ArangoDB database

声明:我是主要开发人员之一。

+0

请不要犹豫,在此提问更多问题Google网上论坛:https://groups.google.com/forum/#!forum/arangodb –