寻求Ruby nested_set gem的切实解释

时间:2013-05-31 22:22:33

标签: ruby-on-rails ruby database-design tree

几年前,我有机会使用Ruby“nested_set”gem工作。通过我所在的首席技术专家的一些有用的解释,我能够通过其专栏来了解它是如何工作的:

在过去的几年里,我没有机会重新考虑它,因为我不经常使用Rails,但现在我想在另一个平台上自己实现它,将一些数据构建为树。所以我正在寻找一个有说服力的解释它是如何工作的,有一个链接或链接,或一个充实的答案。

提前致谢

1 个答案:

答案 0 :(得分:1)

嵌套集类似于adjacency lists,但如果父母和孩子只通过列了解他们的直接联接,则提供额外的操作,这些操作无法轻松执行。

例如,如果我们获得以下数据模型:

  Graph                 Table

     A                  node, parent
    / \                  A,
   B   E                 B,   A
  / \                    C,   B
 C   D                   D,   B
                         E,   A

我们可以轻松地检索节点A的直接子节点,但是如果我们想确定节点C是否在节点A的层次结构中,或者我们想要检索节点A的整个树而不仅仅是它的直接子节点,那么它变得棘手。这很棘手,因为节点C不是节点A的直接子节点,并且不知道树的深度,或者递归查询(不是某些数据库的选项),或者某种SQL voodoo我们几乎都是运气不好另一个可能成为问题的例子是我们想要销毁或更新节点A树中的每条记录。

除了我们的初始父属性之外,嵌套集还引入了“left”和“right”属性。现在节点被编号两次,与插入或修改记录时通过树遍历访问它们的次数相关。将前一个示例与嵌套集一起使用将如下所示:

  +---------------------------+          id, text, lft, rgt
  |             A             |           1, A,    1,   10
  |                           |           2, B,    2,   7
  | +----------------+ +----+ |           3, C,    3,   4
  | |       B        | | E  | |           4, D,    5,   6
  | |                | |    | |           5, E,    8,   9
  | | +----+  +----+ | +----+ |
  | | | C  |  | D  | |        |
  | | |    |  |    | |        |
  | | +----+  +----+ |        |
  | +----------------+        |
  +---------------------------+
  1 2 3    4  5    6 7 8   9  10

通过上面的例子,我们可以确定节点A的左右深度为1&因此,它的层次结构中的任何内容都将在这两个值之间的某处具有左右深度。话虽如此,查询节点A的整个树现在变得微不足道了:

SELECT c.id, c.text, c.lft, c.rgt FROM nodes c, nodes p WHERE p.lft < c.lft AND p.rgt > c.rgt AND p.id = 1;

给我们:

  id, text, lft, rgt
   2, B,    2,   7
   3, C,    3,   4
   4, D,    5,   6
   5, E,    8,   9

请参阅Recursive data structures with rails了解来源。正如问题评论中所讨论的,根据您的要求,可能会有更好/更有效的解决方案 - 链接的文章更详细地介绍了这一点。