Ruby中的树数据结构持久性

时间:2012-03-05 00:27:19

标签: sql ruby serialization tree persistence

我有一个项目,我需要在Ruby中构建和存储大型数据树。我正在考虑不同的序列化,反序列化和查询树的方法,我想知道什么是最好的方法。我的主要限制是读取时间,查询效率和跨版本/跨平台兼容性。最常见的操作是基于id /值和/或特征的组合来检索节点集。树可以高达15-20级。移动子树是一个不常见的过程,但应该可以没有太多的黑魔法。 Rails集成不是主要问题。我想到的选项,以及我关心的一些问题,如下:

  • 对树进行编组,并在需要时将它们加载到内存中并在Ruby中查询它们(效率低下,树增长,跨版本兼容性?)
  • 与上述相同,但使用YAML(更多跨版本兼容,但效率较低?)
  • 与上面相同,但使用自定义XML解析器(每次加载树时都需要从头开始重新创建对象?)
  • 将树序列化为XML,将它们存储在XML数据库(例如Sedna)中,并使用XPath查询树(没有这种方法的经验,不确定效率?)
  • 使用邻接列表查询存储在无模式数据库中的树(计算后代时的效率低下)?
  • 使用物化路径(过度填充深树的最大字符串长度?)
  • 使用嵌套集(复杂的SQL查询?)
  • 使用array of ancestors方法?根据MongoDB页面,在查询效率方面看起来很有趣,但我还没有找到任何关于此算法的认真讨论。

根据您的经验,哪种方法更符合我所描述的限制?如果我选择XML数据库,是否有更适合这个项目的数据库?我忽略了其他更有效的方法吗?谢谢你的时间。

3 个答案:

答案 0 :(得分:3)

树对图数据库非常有效,例如neo4j:http://neo4j.org/learn/

Neo4j 是一个图形数据库,用于存储节点中的数据和图形的关系。最通用的数据结构,图形优雅地表示任何类型的数据,保留域的自然结构。

Ruby有一个很好的树接口: https://github.com/andreasronge/neo4j

Pacer 是一个JRuby库,可以实现非常富有表现力的图遍历。 Pacer允许您使用非常快速且内存有效的流处理来创建,修改和遍历图形。这也意味着几乎所有的处理都是用纯Java完成的,所以当通常的Ruby表现力和速度问题出现时,你可以吃蛋糕并吃掉它,它的速度非常快!

https://github.com/pangloss/pacer

Neography 就像neo4j.rb宝石一样,Ron在评论中提出建议(感谢Ron!)

https://github.com/maxdemarzi/neography

答案 1 :(得分:2)

由于您正在考虑使用SQL方法,因此需要考虑以下事项。

首先,树木有多大?对于许多应用程序,10,000片叶子似乎很大。然而,这对于数据库来说很小。在任何体面的数据库系统(如笔记本电脑)上,您应该能够在内存中存储数千或数百万个叶子。

数据库购买的其他方法是:

- 不必担心内存/磁盘性能。当数据溢出到磁盘时,您不会对性能产生重大影响。相比之下,考虑当哈希表溢出内存时会发生什么。

- 能够添加索引以优化性能。

- 能够通过修改SQL

来“改变”树的访问路径

标准SQL的一个问题是您可以将树节点表示为一对简单对:,,。然后,通过简单的连接,您可以在父项和叶子之间移动。但是,当您向上移动树时,连接会累积。

叹息。不同的数据库有不同的解决方案。 SQL Server具有递归CTE,可以让您遍历树。 Oracle还有另一种树结构方法。

这开始变得复杂。

也许更好的方法是根据树中的层次结构分配“叶子”id。因此,如果这是二叉树,那么“10011”将是右分支,左分支,左分支,右分支,右分支的节点。那里你会存储信息。 。 。比如是否有孩子和其他什么。获取父级很容易,因为您可以截断最后一位数。

您可以看到这将如何推广到非二叉树。拥有任意数量的孩子可能会带来一些挑战。

我相信这可能与“祖先阵列”方法有关。

在我考虑它时,我认为这样可以很好地运作。然后,我建议您为每个所需的操作定义单独的存储过程:

usp_tree_FetchNode(NodeId) usp_tree_GetParent(NodeId) usp_tree_NodeDelete(NodeId) usp_tree_FetchSubTree(NodeId) 等等。

尽管SQL并不真正支持面向对象的编程,但您仍然可以使用干净的命名约定和良好的函数包装器来组织代码。

我实际上认为这可能有用,并为开发代码提供了一个很好的方法。一个很好的副作用是你可以分析应用程序之外的树,这可能暗示未来的增强功能。

答案 2 :(得分:0)

你看过ancestry gem了吗?我已将它用于简单的树木,但根据描述,它看起来符合您的要求。