首页 > 解决方案 > Rails 在递归函数中打开了多少个连接?

问题描述

我有一个模型,它自身具有递归链接,例如链表。如果我正在编写一个像下面这样的函数(请原谅我的语法,Ruby 不是我选择的语言)以跟随链到最后。假设这是 Active Record 模型的一部分并且next是下一个节点的外键,那么这个函数在幕后会发生什么?Active Record 打开了多少与我的 MySQL 数据库的单独连接,它们会持续多长时间?

module LinkedList
  class Node < ActiveRecord::Base

    has_one :value
    has_one :next, foreign_key: 'id' class_name: 'Source::Incident'

    def fetch_all_nodes(current_node=nil, all_nodes=nil)

      current_node = current_node ? current_node : self
      all_nodes = all_nodes ? all_nodes : [self]

      if current_node.next
        all_nodes = fetch_all_nodes(current_node.next, all_nodes << current_node)

      all_nodes
   end
 end
end

标签: ruby-on-rails

解决方案


编写为递归函数,每个节点都有一个调用 SQL 调用。Next 被调用,获取相关节点,并缓存值。(如果需要,您可以重新加载它)。据我所知,这个实现最终每个数据库记录都有一个对象。如果你最终查找了一个已经存储的对象,这将导致更多的对象和更多的数据库查找,但 Rails 有一个查询缓存,因此可以减少此类查找。

您可以all_nodes改为返回一个惰性枚举器,然后如果您最终不检查整个尾部,则每个访问的节点只有一个调用,并且您可以处理潜在的无限(甚至循环)列表。


推荐阅读