index:true vs foreign_key:true(Rails)

时间:2016-09-15 05:20:24

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

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

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。这两者之间的区别是什么?

3 个答案:

答案 0 :(得分:13)

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

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

它将在student_id表格中创建appointments列。

外键具有不同的用例,它是表之间的关系。它允许我们在一个表中声明一个与另一个表中的索引相关的索引,并且还放置了一些约束。数据库强制执行此关系的规则以维护参照完整性。例如,我们有两个表profileseducations,而个人资料可能有很多教育。

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

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

答案 1 :(得分:5)

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

参考
声明引用时,您只是在说要包括一列其值应与另一个表的值匹配的列(在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

答案 2 :(得分:-1)

为了获得良好的效果,您可以添加index: trueforeign_key: true,但不是必需的。

索引为数据库中的搜索提供了更好的选择,因此速度更快。

外键强制引用完整性。您可以阅读有关外键here

的更多信息