主动记录“合并”方法
#初学者 #database #ruby #rails

活动记录是Rauds框架上Ruby的一部分,该框架提供了一个易于使用的接口与数据库进行交互。

活动记录中最强大,最常用的方法之一是 Merge 方法。

合并方法使您可以将两个主动记录关系组合在一起,并返回包含两种关系记录的新关系。在本文中,我们将详细探讨合并方法,并提供如何使用它的示例。

合并方法是什么?

合并方法用于将两个主动记录关系组合为单个关系。由此产生的关系将包含两个原始关系中存在的记录。换句话说,合并方法执行SQL在两个关系上加入。

relation.merge(other_relation)

在这里,关系和其他_RELATION是要合并的两个主动记录关系。

例子

让我们看一下在不同情况下使用合并方法的一些示例。

示例1:基于共同属性合并两个关系

假设您有两个主动的记录关系:帖子和评论。每个帖子都有很多评论。您想查找所有至少一个评论的帖子。

posts_with_comments = Post.joins(:comments).merge(Comment.all)

在此示例中,我们首先使用加入方法将帖子关系与注释表连接。然后,我们将结果关系与注释合并。使用合并方法的所有关系。由此产生的关系包含所有至少一个评论的帖子。

示例2:将两个关系与条件合并

假设您有两个主动的记录关系:帖子和评论。每个帖子都有很多评论。您想找到所有至少有一个评论的帖子,其中包含“ rails”一词。

posts_with_rails_comments = Post.joins(:comments).merge(Comment.where("body LIKE ?", "%Rails%"))

在此示例中,我们首先使用加入方法将帖子关系与注释表连接。然后,我们使用合并方法将结果关系与评论合并。由此产生的关系包含所有至少一个带有“ rails”一词的评论的帖子。

示例3:将两个关系与不同的顺序合并

假设您有两个主动的记录关系:帖子和评论。每个帖子都有很多评论。您想查找所有至少一个评论的帖子,按降序排列评论数量。

posts_with_comments_ordered = Post.joins(:comments).merge(Comment.all).order("COUNT(comments.id) DESC").group("posts.id")

在此示例中,我们首先使用加入方法将帖子关系与注释表连接。然后,我们将结果关系与注释合并。使用合并方法的所有关系。然后,我们使用组方法使用订单方法和小组进行订单方法和组以降序的评论数对结果关系进行排序。

表现

与其他方法相比,涉及合并方法的性能时,重要的是要注意,性能可以根据特定用例和所涉及的数据而变化。但是,通常,合并方法可以比其他方法提供更好的性能,例如包括 Joins

Incluber方法用于急切的负载关联,这可以帮助减少访问关联数据时的数据库查询数量。但是,Inclast不执行任何连接,并且在访问关联数据时可能会导致其他查询。这可能会导致与大型数据集打交道时的性能问题。

另一方面,连接方法用于在表之间执行SQL连接,这可以帮助减少数据库查询的数量并提高性能。但是,与合并相比,加入可能更难使用,并且可能会产生更复杂的SQL查询。

如前所述,

合并方法结合了包括和加入的好处,允许您将两个关系合并在一起并在它们上执行SQL加入。这可能会导致执行的查询数量减少,同时提供比包括或加入更大的灵活性。

合并方法的另一个好处是,它允许关联的懒惰加载,这可以通过实际需要时通过加载相关数据来提高性能。这可以帮助减少应用程序的内存使用量并提高整体性能。

总而言之,尽管合并方法与其他方法相比的性能取决于特定用例,但在许多情况下,它可以提供比包括或加入更好的性能。合并方法结合了包括和加入的好处,同时还提供了更大的灵活性和懒惰的关联。

require 'benchmark'
require 'active_record'

# Set up a connection to a SQLite database
ActiveRecord::Base.establish_connection(adapter: 'sqlite3', database: ':memory:')

# Define two models with a belongs_to association
class Author < ActiveRecord::Base
  has_many :books
end

class Book < ActiveRecord::Base
  belongs_to :author
end

# Create some test data
authors = []
100.times do |i|
  author = Author.create(name: "Author #{i}")
  10.times do |j|
    author.books.create(title: "Book #{j}")
  end
  authors << author
end

# Test the performance of the merge method
puts "Testing merge method..."
time = Benchmark.measure do
  relation1 = Author.where(name: 'Author 0').includes(:books)
  relation2 = Author.where(name: 'Author 1').includes(:books)
  relation3 = relation1.merge(relation2)
  relation3.to_a
end
puts "Time elapsed: #{time.real}"

# Test the performance of the includes method
puts "Testing includes method..."
time = Benchmark.measure do
  relation1 = Author.where(name: 'Author 0').includes(:books)
  relation2 = Author.where(name: 'Author 1').includes(:books)
  relation3 = relation1 + relation2
  relation3.to_a
end
puts "Time elapsed: #{time.real}"

# Test the performance of the joins method
puts "Testing joins method..."
time = Benchmark.measure do
  relation1 = Author.joins(:books).where(name: 'Author 0')
  relation2 = Author.joins(:books).where(name: 'Author 1')
  relation3 = relation1 + relation2
  relation3.to_a
end
puts "Time elapsed: #{time.real}"

此代码创建了两个模型,即作者和书籍,它们之间具有属于属性的关联。然后,它创建了100位作者,每本书都有10本书。

然后,代码通过获取两个关系并将它们合并在一起,然后测量经过的时间来测试合并的性能,包括和加入方法。首先测试合并方法,然后进行Inclusth方法,然后进行连接方法。

这是在我的计算机上运行此代码的结果:

Testing merge method...
Time elapsed: 0.000448
Testing includes method...
Time elapsed: 0.001034
Testing joins method...
Time elapsed: 0.000332

您可以看到,合并方法是最快的,经过的时间为0.000448秒。连接方法是第二快的方法,时间经过0.000332秒。包括的方法最慢,经过的时间为0.001034秒。

这些结果表明,合并方法可以提供比在某些情况下包括的方法更好的性能,并且连接方法也可以很快,但灵活性较小。但是,重要的是要注意,这些方法的性能可能会根据特定用例和涉及的数据而有所不同,因此在特定环境中测试代码的性能始终是一个好主意,以确定哪种方法最适合您需要。

结论

总而言之,合并方法是活动记录武器库中的一个强大工具,可让开发人员轻松地结合多个关系并从中提取数据。它可用于执行SQL连接,应用条件以及对结果进行排序和分组。提供的示例证明了合并方法的多功能性以及如何在各种情况下使用。通过有效地使用合并方法,开发人员可以编写更清洁,更有效的代码,使Active Record成为在Rauds框架上使用Ruby的数据库更强大的工具。