我有一个项目,我需要在Ruby中构建和存储大型数据树。我正在考虑不同的序列化,反序列化和查询树的方法,我想知道什么是最好的方法。我的主要限制是读取时间,查询效率和跨版本/跨平台兼容性。最常见的操作是基于id /值和/或特征的组合来检索节点集。树可以高达15-20级。移动子树是一个不常见的过程,但应该可以没有太多的黑魔法。 Rails集成不是主要问题。我想到的选项,以及我关心的一些问题,如下:
根据您的经验,哪种方法更符合我所描述的限制?如果我选择XML数据库,是否有更适合这个项目的数据库?我忽略了其他更有效的方法吗?谢谢你的时间。
答案 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!)
答案 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了吗?我已将它用于简单的树木,但根据描述,它看起来符合您的要求。