【问题标题】:How did my old create joined tables work with no indexes?我的旧创建联接表如何在没有索引的情况下工作?
【发布时间】:2019-06-03 21:52:30
【问题描述】:

我之前使用迁移创建了一个连接表:

class CreateJoinTableCategoryListing < ActiveRecord::Migration[5.2]
  def change
    create_join_table :categories, :listings do |t|
      # t.index [:category_id, :listing_id]
      # t.index [:listing_id, :category_id]
    end
  end
end

我正在回顾这一点,因为我将要创建一个新的连接表。但是在查看它时,我注意到我迁移时 t.index 仍然被注释掉,并且连接的表仍然正常运行。

我阅读了这篇文章,但我没有找到任何关于有人这样做或不需要他们的帖子。

对于那些从未迁移过的索引,它是如何操作的?它们的需求如何?

我正在创建一个新的迁移:

class CreateJoinTable < ActiveRecord::Migration[5.2]
  def change
    create_join_table :users, :affiliates do |t|
      # t.index [:user_id, :affiliate_id]
      # t.index [:affiliate_id, :user_id]
    end
  end
end

我应该在这里选择哪个索引?

它的工作原理是会员能够手动向表格提交“佣金”(确实需要将其添加到迁移中),但如果佣金被更新,它应该取代列而不是创建新行。

用户实际上与此无关,并且主要由会员更新,以更新他们对用户的佣金率。

更新:

是否可以在连接表中添加另一个字段?

我想在表格中添加一个 :commission,但我找不到任何文档可以为此做任何事情。我应该只在用户表中定义佣金率并取消连接表吗?

更新 2:

最终放弃了这个想法,并仅与用户和附属协会保持我目前的做法。我取消了 UsersAffiliates 的想法,因为这种情况不需要它。

【问题讨论】:

  • 索引加快了搜索速度。因此,您仍然可以在没有它们的情况下搜索特定记录,但速度较慢。
  • 查看我在数据库中的连接表时。它有listing_id 和category_id。它们只是自动添加吗?还有 - 我应该创建任何新的迁移来帮助这个吗?
  • 是的,列本身是通过create_join_table 方法自动添加的,请看这里:rubydoc.info/github/rails/rails/… 是的,要添加您需要的索引,您可能应该创建另一个迁移。
  • 嗯...好的,我会更新的。我添加了我需要做的迁移并且对我应该如何选择哪一个感到困惑。我很困惑,因为它们看起来基本相同,只是顺序不同。而你发给我的链接并没有显示出同样的数组使用风格
  • 这取决于您打算按哪一列搜索此表(或者可能同时搜索两者)。

标签: ruby-on-rails ruby


【解决方案1】:

对于那些从未迁移过的索引,它是如何运行的以及如何需要 是吗?

Rails 中所有类型的关联都可以在没有索引的情况下工作。唯一需要的是存在正确的表和列。

然而,随着数据库大小的增长,索引对性能至关重要。它们还提供诸如唯一性等约束,以确保duplicate data cannot be inserted due to race conditions

我应该在这里选择哪个索引?

Rails 生成两个不同索引的全部原因是您应该选择与您最常搜索表的方式相对应的索引。例如,如果您最常使用User.joins(:affilitates),您会选择t.index [:user_id, :affiliate_id]

它的工作原理是会员能够手动提交 表中的“佣金”(确实需要添加到 迁移)。

create_join_table 宏创建一个以has_and_belongs_to_many 关联命名的连接表。

has_and_belongs_to_many 关联的主要问题是它们是无头的。没有模型,因此无法直接查询表或添加其他元数据列。

您想要的是has_many :through 关联。

class User < ApplicationRecord
  has_many :user_affiliates
  has_many :affiliates, through: :user_affiliates
end

class Affiliate < ApplicationRecord
  has_many :user_affiliates
  has_many :affiliates, through: :user_affiliates
end

# call this whatever you want
class UserAffiliate  < ApplicationRecord
  belongs_to :user
  belongs_to :affilitate
end

虽然has_and_belongs_to_many 使用表命名方案users_affilities (plural_plural),但您想使用user_affilities 来建立has_many through: 关联。

您可以通过以下方式解决此问题:

  1. 只是通过普通的生成器rail g model user_affiliate生成表/模型。
  2. 如果表存在write a migration to rename the table

但如果委员会更新,它应该取代 列,而不是创建新行。

您可以通过以下方式解决此问题:

  1. t.index [:user_id, :affiliate_id], unique: true 两列上添加唯一复合索引。
  2. 在连接模型中添加唯一性验证。 validates_uniqueness_of :user_id, scope: :affiliate_id
  3. 在控制器中使用.find_or_initialize_by 更新现有行(如果存在),而不是创建新行(如果已存在)。

【讨论】:

  • 好吧,我读到您不能/不应该将列添加到可连接件中。我以前想加入用户和附属公司,并在同一张表中拥有佣金属性 - 但显然,我可能错了,你不能这样做。截至目前,我刚刚将佣金添加到用户表中,因为佣金将取决于每个用户
  • 你要么真的误读了某些东西,要么应该对你所读的 cr*p 更加挑剔。有很多有效的案例,您希望将附加数据附加到连接表。它们没有什么神奇之处,它只是一个带有两个外键列的表。它可以做到——只是没有 has_and_belongs_to_many。
  • 并且将列添加到用户表中根本不是一回事。它将固定每个用户的价值,而后者是每个组合唯一的。
  • 你说得对,我用佣金创建了连接表。但至于这样做的用户表,我已经通过affiliate_id 建立了一个affilaite 关联
  • 哇,我是个白痴。刚读了你写的,我喜欢它。试一试。但是,这会比只在用户表中设置佣金并允许会员以这种方式更新它更有益吗?表单输入是否会由于关联而在提交后自动生成到 UserAffiliate 表的记录?还是需要控制器?
猜你喜欢
  • 2018-01-31
  • 2019-06-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-02-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多