急切加载与联接提取相同吗?

时间:2011-03-16 08:22:27

标签: sql ruby-on-rails orm activerecord

渴望获取与联接提取相同吗?

我的意思是,是否急切地获取有多少关系会激发2个查询或单个连接查询?

rails active记录如何实现关联的连接提取,因为它不知道表的第一手元数据(我的意思是表中的列)?比方说,我有

人 - 身份,姓名 东西 - id,person_id,名称

人与事物有一对多的关系。那么它如何生成包含所有列别名的查询,即使在我对人们进行连接提取时它无法知道呢?

2 个答案:

答案 0 :(得分:3)

答案尚未被接受,因此我将尽力回答您的问题:

  • “它如何知道表中可用的所有字段?”

它为从ActiveRecord :: Base继承的每个类执行SQL查询。如果该类是'Dog',它将进行查询以查找表'dogs'的列名。在生产模式下,它应该只在每次运行服务器时执行一次查询 - 在开发模式下它会做很多事情。查询将根据您使用的数据库而有所不同,通常是一个昂贵的查询。

  • “如果我在表格和相关联的表格中有相同的名称,它是如何解决此问题的?”

如果您正在进行连接,它会使用表名作为前缀生成sql,以避免歧义。实际上,如果您在Rails中进行连接并希望为name添加条件(使用自定义SQL),但主表和连接表都有一个名称列,则需要在sql中指定表名。 (例如Human.join(:pets).where(“humans.name ='John'”))

  • “我的意思是,是否急切地获取有多少关系会触发2个查询或单个连接查询?”

不同的Rails版本不同。我认为早期版本始终只进行一次连接查询。更高版本有时会执行多个查询,有时会进行单个连接查询,这是基于单个连接查询并不总是与多个查询一样高效的实现。我不确定它用来决定的确切逻辑。最近,在Rails 3中,我看到在我当前的代码库中发生了多个查询 - 但也许它有时会进行连接,我不确定。

答案 1 :(得分:1)

它通过一种反射来了解列。 Ruby非常灵活,允许您构建将在运行时使用/定义的功能,而不需要提前说明。它通过解释“belongs_to:person”并且知道“person_id”是将被关联的字段并且该表将被称为“人”来学习关联的“person_id”列。

如果您执行People.includes(:things),那么它将生成2个查询,1个获取人员,第二个获取与存在的人有关系的事物。

http://guides.rubyonrails.org/active_record_querying.html