【问题标题】:Rails self-referential hierarchical relationshipRails 自引用层次关系
【发布时间】:2017-11-28 21:58:10
【问题描述】:

我已经阅读了 Rails 指南并尝试了一些使用 Active Record 的不同方法,但无法弄清楚最好的方法是什么。

我需要建立一个分层的自我参照(用户到用户)关系。它通常不会超过 5 级高,但应该能够无限放大。

我尝试使用如下 DB 架构创建 UserHierarchy 模型:

parent | child | level

但是,管理这个有点太难了,太复杂了。

Rails 中建立自引用层次关系的最佳方式是什么?我已经检查过像祖先这样的宝石,但它们中的大多数都使用类继承,并且不适用于自引用关系。这是一个多对多、自引用的层次结构(在 MySQL 中)。

【问题讨论】:

  • 您尝试实施的业务用例是什么?一个级别的用户与另一级别的用户有什么关系?
  • 我不确定我是否理解关卡的必要性;用户有嵌套用户。水平是关系的内在因素。如果你在网上搜索自我参照关系,你应该会找到你需要的一切。

标签: ruby-on-rails activerecord


【解决方案1】:

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

一般来说,在 SQL 数据库中存储树的常用方法大约有四种:

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

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

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-01-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多