【问题标题】:index: true vs foreign_key: true (Rails)index: true vs foreign_key: true (Rails)
【发布时间】:2017-01-23 00:53:39
【问题描述】:

按照指南,我运行了以下命令:

rails g migration CreateSnippetsUsers snippet:belongs_to user:belongs_to

这创建了以下迁移:

class CreateSnippetsUsers < ActiveRecord::Migration[5.0]
  def change
    create_table :snippets_users do |t|
      t.belongs_to :snippet, foreign_key: true
      t.belongs_to :user, foreign_key: true
    end
  end
end

过去我也看到过同样的事情,但使用的是index: true 而不是foreign_key: true。两者有什么区别?

【问题讨论】:

标签: ruby-on-rails rails-activerecord ruby-on-rails-5 rails-migrations


【解决方案1】:

索引提高了对数据库表的数据检索操作的速度。当我们将index: true 写入任何列时,它会向该列添加一个数据库索引。例如我正在创建一个表:

    create_table :appointments do |t|
      t.references :student, index: true 
    end

它将在appointments 表中创建student_id 列。

外键有不同的用例,它是表之间的关系。它允许我们在一个表中声明与另一个表中的索引相关的索引,并放置一些约束。数据库强制执行这种关系的规则以保持引用完整性。例如我们有两个表profileseducations,并且一个配置文件可能有很多教育。

create_table :educations do |t| 
  t.belongs_to :profile, index: true, foreign_key: true
end

现在我们在educations 表中有profile_id 列,它是profiles 表的外键。它会阻止将记录输入到educations 表中,除非它包含存在于profiles 表中的profile_id 值。因此将保持参照完整性。

【讨论】:

  • 不会t.references :studentappointments 表中创建student_id 列吗?如果是这样,index: true 做了什么?
  • index: true 在这里做索引。
【解决方案2】:

索引外键外键约束是数据库中经常混淆或混淆的严格相关概念误会了。

参考文献
当您声明一个reference 时,您只是说要包含一个值应该与另一个表的值匹配的列(在 Rails 中,您还可以获得一些有用的方法来浏览关联的模型)。在示例中:

create_table :appointments do |t|
  t.references :student
end

appointments 表将有一个名为 student_id 的列,其值应位于学生 id 值池中。

索引
因为当您添加引用时,您可能会经常使用该列,您可能(并且可能应该!)还告诉您数据库使用引用列来提高查找速度。您可以使用选项index: true 来执行此操作(顺便说一下,这是自Rails 5 以来reference 方法中的默认选项)。索引几乎没有缺点,主要是内存消耗较大。

外键限制
从目前所说的来看,reference columnforeign column 是同义词。但是您还记得我说过引用列的值应该与另一个表的值匹配吗?如果您只是声明一个引用,则您有责任确保引用表上的匹配行存在,否则有人最终会执行无意义的操作,例如为不存在的学生创建约会。这是数据库完整性的一个例子,幸运的是,有一些机制可以提供更高级别的完整性。这些机制称为“数据库约束”foreign_key: true 选项所做的正是在引用列上添加这种约束,以拒绝任何外键值不在引用表中的条目。

数据库完整性是一项复杂的任务,随着数据库的复杂性而增加难度。您可能还应该添加其他类型的约束,例如在课堂上使用关键字 dependent: :destroy 以确保当您删除学生时,其所有现有约会也会被销毁。

像往常一样,这是一个 RTFM 链接:https://guides.rubyonrails.org/association_basics.html

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-12-23
    • 2012-03-23
    • 2018-02-18
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多