代码之家  ›  专栏  ›  技术社区  ›  Joe Cannatti

在Rails中有许多使用连接

  •  1
  • Joe Cannatti  · 技术社区  · 15 年前

    我对rails中has-many关系的理解是,它将使用join来查找相关的行。如果我从头开始实现这一点,我将创建一个关系表。我认为使用join会比较慢,对吗?在Django中,我相信关系表是被创建的,并且我知道如果我愿意,可以在Rails中使用关系表。我想知道为什么这是默认行为,它是否会有任何区别。

    谢谢

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

    不,默认情况下, 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) 
    

    但是,如果 哈萨尔多 关系定义 :through :include 选项,SQL将导致一个联接,但正确地说是这样。

        2
  •  1
  •   Mike Woodhouse    15 年前

    在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 表,后者具有外键 order_id 对其父订单的引用。

    Order.find(some_id)
    

    将检索单个订单。 订单项目 除非您显式引用它,或者将指令添加到类定义中以要求始终导航关联,否则不会被触碰。

    不过,我不知道为什么你这么关心使用连接。有了适当的索引,几乎任何现代DBMS都将是高效的:这就是它们的设计目的。

        3
  •  1
  •   Tomas Markauskas    15 年前

    如果您不告诉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)) 
    

    如果您不需要/不想加入,那么就不会有加入。