按照指南,我运行了以下命令:
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
。两者有什么区别?
索引、外键和外键约束是数据库中严格相关的概念,经常被混淆或误解。
参考文献
当你声明一个 reference 时,你只是说要包含一个列,其值应该与另一个表的值匹配(并且在 Rails 中,你还可以获得一些有用的方法来浏览关联的模型)。在示例中:
create_table :appointments do |t|
t.references :student
end
appointments
表将有一个名为 student_id
的列,其值应位于学生 ID 值池中。
索引
由于当您添加引用时,您可能会经常使用该列,因此您可以(并且可能应该!)还告诉您数据库使用引用列来提高查找速度。您可以使用选项
index: true
来完成此操作(顺便说一下,自 Rails 5 以来,这是 reference
方法中的默认选项)。索引几乎没有缺点,主要是内存消耗较大。
外键限制
从目前来看,
reference column
和foreign column
是同义词。但是您还记得我说过参考列的值应该与另一个表的值匹配吗?如果您只是声明引用,则您有责任确保引用的表上存在匹配的行,否则有人最终会执行无意义的操作,例如为不存在的学生创建约会。这是数据库完整性的一个例子,幸运的是,有一些机制可以授予更强的完整性级别。这些机制称为“数据库约束”。选项foreign_key: true
所做的正是在引用列上添加这种约束,拒绝任何外键值不在引用表中的条目。数据库完整性是一项复杂的任务,随着数据库的复杂性而变得越来越困难。您可能还应该添加其他类型的约束,例如在班级中使用关键字 dependent: :destroy
,以确保当您删除学生时,其所有现有约会也会被销毁。
与往常一样,这里有一个 RTFM 链接:https://guides.rubyonrails.org/association_basics.htmlindex: true
时,它会向该列添加数据库索引。例如我正在创建一个表:
create_table :appointments do |t|
t.references :student, index: true
end
它将在
student_id
表中创建
appointments
列。 外键有不同的用例,它是表之间的关系。它允许我们在一个表中声明与另一表中的索引相关的索引,并且还设置一些约束。数据库强制执行这种关系的规则以维护引用完整性。例如我们有两个表
profiles
和
educations
,并且一个配置文件可能有很多教育背景。 create_table :educations do |t|
t.belongs_to :profile, index: true, foreign_key: true
end
现在我们在
profile_id
表中有
educations
列,它是 profiles
表的外键。它会阻止记录输入到 educations
表中,除非它包含 profile_id
表中存在的 profiles
值。因此将保持引用完整性。