索引:真实与 foreign_key:真实(Rails)

index: true vs foreign_key: true (Rails)

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

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。两者有什么区别?

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

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

它将在 appointments table 中创建 student_id 列。

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

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

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

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

参考文献
当你声明一个 reference 时,你只是说要包含一个列,其值应该与另一个 table 的列相匹配(在 Rails 中你也会得到一些有用的在关联模型中导航的方法)。在示例中:

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

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

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

外键约束
到目前为止,reference columnforeign column 是同义词。但是您还记得我说过引用列的值 应该 与另一个 table 的值匹配吗?如果您只是声明一个引用,您有责任确保所引用的 table 上的匹配行存在,否则有人最终会做出无意义的操作,例如为 non-existing 学生创建约会。这是 数据库完整性 的示例,幸运的是,有一些机制可以授予更高级别的完整性。这些机制被称为'数据库约束'。选项 foreign_key: true 所做的就是在引用列上添加这种约束,以拒绝任何其外键值不在引用的 table.

中的条目

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

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