代码之家  ›  专栏  ›  技术社区  ›  kikito

Rails+ActiveRecord:缓存模型的所有寄存器

  •  1
  • kikito  · 技术社区  · 15 年前

    我有一个小模型(我们称之为“节点”),它表示一个树状结构。每个节点只包含一个名称和对其父节点的引用:

    class Node < ActiveRecord::Base
      validates_presence_of :name, :parent_id
    end
    

    这张桌子不太大——少于100个元素。它很少更新-在过去的4个月里,网站管理员在一次中添加了20个新元素。

    但是它在我的应用程序中被大量使用。考虑到它的树型结构,在某些情况下,一个请求会触发超过30次数据库命中(包括Ajax调用,我经常使用)。

    我想使用某种缓存来降低数据库访问-由于表太小,我考虑将所有寄存器缓存到内存中。

    这可能是轨道2.3吗?有没有更好的方法来解决这个问题?

    3 回复  |  直到 15 年前
        1
  •  2
  •   tadman    15 年前

    为什么你不每次都装,以避免被多个负载击中?

    下面是一个简单的例子:

    before_filter :load_all_nodes
    
    def load_all_nodes
      @nodes = Node.all.inject({ }) { |h, n| h[n.id] = n; n }
    end
    

    这将为您提供一个按节点ID索引的哈希,以便您可以使用此缓存代替查找调用:

    # Previously
    @node = Node.find(params[:id])
    
    # Now
    @node = @nodes[params[:id].to_i]
    

    对于小而简单的记录,在一次提取中快速加载它们是一个相当便宜的操作。

        2
  •  1
  •   Steve Weet    15 年前

    你看过任何一个能提供树状行为的插件吗?

    Ryan Bates有一个 railscast 但是在行为上 acts_as_nested_set 或其他受其启发的项目,例如 awesome_nested_set acts_as_better_nested_set 也许更适合你的需要。

    这些项目允许您通过一个SQL查询获取一个节点及其所有子节点。这个 acts_as_better_nested_set site 对该方法的工作方式有很好的描述。

        3
  •  0
  •   kikito    15 年前

    从几个方面看,我认为塔德曼的解决方案是最简单的。

    为了获得更灵活的解决方案,我找到了以下要点:

    http://gist.github.com/72250/

    当做!