Rails自引用层次关系

时间:2015-03-25 19:47:17

标签: ruby-on-rails activerecord

我已经阅读了Rails指南并尝试了一些与Active Record不同的东西,但还没有找到最佳方法。

我需要建立一个层次结构的自引用(用户到用户)关系。它通常不会超过5级,但应该能够无限扩大。

我尝试使用这样的数据库架构创建UserHierarchy模型:

parent | child | level

然而,管理这个有点太困难,太复杂,无法处理。

Rails执行自引用层级关系的最佳方式是什么?我已经检查过像祖先这样的宝石,但是他们中的大多数都使用了阶级继承,并且不能很好地用于自我指涉关系。它是一个多对多,自引用的层次结构(在MySQL中)。

1 个答案:

答案 0 :(得分:2)

Ancestry是特别的宝石之一。非常适合对象树结构(你称之为自引用层次关系)。你应该更详细地看一下它。

通常,在SQL数据库中存储树有四种常用方法:

  • 简单的父指针。您只需将一个名为parent_id的新列添加到包含父对象ID的模型中。这允许简单插入,非常适合单级层次结构,但通常难以用于更深层次结构,因此通常不用作主要机制(尽管有时与其他机制结合使用)
  • Nested Sets您可以将树定义为嵌套集的结构。这通常使用rightleft列来实现,这些列填充有数字以定义集合。它允许有效的查询,但在插入值时有点棘手。 ESP。当对树进行并发更改时,有时会出现不一致的情况。这个模型是例如用于awesome_nested_set宝石。
  • Materialized Paths这是例如由ancestry使用。它存储所有元素的完整父路径。这允许有效的插入和查询。更换树有点贵。
  • Closure Trees此机制将每个元素的所有父元素存储在一个表中。这是例如由closure_tree gem使用。

通常,所有这些选项都允许存储对象树,即同一类对象的层次结构(在这种情况下为ActiveRecord模型)。

使用哪一个取决于哪种权衡对您的特定用例更为重要。最重要的是,您应该弄清楚您是否经常更换树木(例如移动子树或仅添加树叶)以及您如何查询树木(例如,您是否只需要直接的孩子,是否需要整个子树,你需要过滤)并根据它选择合适的解决方案。