我对Rails中has_many关系的理解是它将使用JOIN来查找相关的行。如果我从头开始实现这个,我会创建一个关系表。我是否认为使用JOIN会更慢?在Django中,我相信关系表是创建的,我知道如果我愿意,我可以在Rails中使用关系表。我想知道为什么这是默认行为,如果它有任何不同。
由于
答案 0 :(得分:2)
不,默认情况下,has_many
关系不使用联接查找相关行。这是一个快速的命令行会话,显示了这一点(我的脚本/控制台启用了调试记录器)。
$ rails has_many_test
$ cd has_many_test
$ ruby script/generate model account
$ ruby script/generate model user account_id:integer
$ rake db:migrate
$ ruby script/console
Loading development environment (Rails 2.3.4)
>> Account.has_many :users
>> a = Account.create
Account Create (0.4ms) INSERT INTO "accounts" ("created_at", "updated_at") VALUES('2009-11-28 18:06:50', '2009-11-28 18:06:50')
>> a.users
User Load (0.3ms) SELECT * FROM "users" WHERE ("users".account_id = 1)
但是,如果has_many
关系定义了:through
或:include
选项,则SQL将导致JOIN,但正确如此。
答案 1 :(得分:1)
如果您不告诉它,Rails将不会使用任何联接。
假设您拥有User
模型has_many :posts
:
User.all
# SELECT * FROM `users`
User.all :joins => :posts
# SELECT `users`.* FROM `users` INNER JOIN `posts` ON posts.user_id = users.id
User.all :include => :posts
# SELECT * FROM `users`
# SELECT `posts`.* FROM `posts` WHERE (`posts`.user_id IN (1,2))
如果您不需要/想加入则不会加入。
答案 2 :(得分:1)
在ActiveRecord(默认情况下在Rails中使用的ORM但不是唯一可能的ORM)中,has_many
关系通常涉及两个模型,因此涉及两个表。所以这些模型:
class Order < ActiveRecord::Base
has_many :order_items
end
class OrderItem < ActiveRecord::Base
belongs_to :order
end
...将引用orders
和order_items
表,后者对其父订单有一个foreign_key order_id
引用。
Order.find(some_id)
将检索单个订单。除非您明确引用它,否则不会触及order_items
,或者将指令添加到类定义中以要求始终导航关联。
我不确定你为什么如此担心使用连接。通过适当的索引,几乎任何现代DBMS都将是高效的:它就是他们的目标。