index:true vs foreign_key:true(Rails)

Mir*_*318 13 ruby-on-rails rails-migrations rails-activerecord ruby-on-rails-5

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

rails g migration CreateSnippetsUsers snippet:belongs_to user:belongs_to
Run Code Online (Sandbox Code Playgroud)

这创建了以下迁移:

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
Run Code Online (Sandbox Code Playgroud)

在过去,我见过同样的事情,而index: true不是foreign_key: true.这两者有什么区别?

Mri*_*yay 14

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

    create_table :appointments do |t|
      t.references :student, index: true 
    end
Run Code Online (Sandbox Code Playgroud)

它将student_idappointments表中创建列.

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

create_table :educations do |t| 
  t.belongs_to :profile, index: true, foreign_key: true
end
Run Code Online (Sandbox Code Playgroud)

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


Cla*_*ani 14

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

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

create_table :appointments do |t|
  t.references :student
end
Run Code Online (Sandbox Code Playgroud)

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

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

FOREIGN KEY CONSTRAINTS
From what said so far, reference column and foreign column are synonyms. But do you remember when I said that a reference column's values should match those of another table? If you simply declare a reference, it's your responsibility to ensure that a matching row on the referenced table exists, or someone will end up doing nonsense actions like creating appointments for non-existing students. This is an example of database integrity, and fortunately there are some mechanisms that will grant a stronger level of integrity. These mechanisms are called ' database constraints'. What the option foreign_key: true 确实是在引用列上添加这种约束,以拒绝任何外键值不在引用表中的条目。

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

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