在Rails应用程序中将外键添加到数据库

时间:2016-03-08 12:02:34

标签: ruby-on-rails ruby database postgresql

使用PostgreSQL,我知道Rails不会在数据库中使用外键并通过Active Record Associations has_one,has_many ....和其他许多处理所有关系,我知道有像{{3这样的宝石可以帮助解决这个问题,

但是将外键添加到数据库表是否值得加速?为什么有人可能会想要添加它?

3 个答案:

答案 0 :(得分:2)

我认为foreign key constraints是确保数据完整性和一致性的工具。

database index用于加速查询。

它们看似相似,经常在相同的环境中使用,但它们并不相同。

顺便说一下,没有必要使用像Foreigner这样的宝石。从开箱即用的Rails 4.2开始支持外键。看看add_foreign_key

add_foreign_key :posts, :users

或者您可以使用foreign_keybelongs_to数据类型上提供的references

create_table :posts do |t|
  t.references :user, foreign_key: true
  t.timestamps
end

答案 1 :(得分:1)

Rails(或ActiveRecord)只是数据库中条目的简单ORM。它不使用DB提供的大多数功能。部分原因是因为他们希望与数据库无关,而且许多更高级的功能都是DBM特有的。但也因为有些人认为将逻辑放入数据库是所有邪恶的根源。

这并不意味着一切都是邪恶的,但应该谨慎使用。特别是存储过程。也就是说,我认为,外键约束和索引在Rails中使用不足。创建它们没有太多缺点(除了播种)。

例如,您可以在has-one关系上使用唯一键约束来防止多个记录。 Rails默认不这样做。您可以依赖验证,但使用DB是更安全的选择:

add_index :child_table, [:parent_id], unique: true

您还可以利用外键约束自动让DB删除依赖记录:

add_foreign_key :children, :parents, column: :parent_id, dependent: :delete

您可以将两者结合起来:

add_foreign_key :children, :parents, column: :parent_id, dependent: :delete, index: { unique: true }

有许多方法可以利用数据库来确保数据的完整性和一致性。

如果您现在使用引用创建rails迁移,它实际上会为您创建索引和外键约束:

 ~blog $ rails g model Post author:references title:string content:text

Running via Spring preloader in process 33539
      invoke  active_record
      create    db/migrate/20160308141214_create_posts.rb
      create    app/models/post.rb
      invoke    test_unit
      create      test/models/post_test.rb
      create      test/fixtures/posts.yml

~/blog $ cat db/migrate/20160308141214_create_posts.rb

class CreatePosts < ActiveRecord::Migration
  def change
    create_table :posts do |t|
      t.references :author, index: true, foreign_key: true
      t.string :title
      t.text :content

      t.timestamps null: false
    end
  end
end

答案 2 :(得分:0)

实际上,ActiveRecord的关系需要数据库中的外键。按照惯例,它的名称是O(n^2)

Documentaiton:http://guides.rubyonrails.org/association_basics.html#the-belongs-to-association (寻找关键词'迁移')

编辑:

在列上添加索引实际上可以帮助您更快地进行查询。 PostgreSQL自动为每个主键约束创建一个索引,但是没有必要添加外键约束来获得索引列。

因此,只要您的{table}_idid列上有索引,就不需要添加foreign_key约束来加速查询。