2016-03-08 132 views

回答

2

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

database index用于加快查询速度。

他们看起来很相似,经常在相同的背景下使用,但他们不一样。


顺便说一句,没有必要使用像外国人一样的宝石。从Rails 4.2开箱即可支持外键。看看add_foreign_key

add_foreign_key :posts, :users 

或者你可以使用foreign_key上可用的belongs_toreferences数据类型:

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

我认为你在这点上是正确的,数据的完整性和一致性是导致Rails应用数据库中外键的主要原因。 –

0

实际上,ActiveRecord的关系在数据库中需要一个外键。按照惯例,它的名字是{table}_id

载文:http://guides.rubyonrails.org/association_basics.html#the-belongs-to-association (查找关键字 '迁移')

编辑:

列上添加一个索引实际上可以帮助你做出更快的查询。 PostgreSQL会自动为每个主键约束创建一个索引,但不需要添加外键约束来创建索引列。

因此,只要您在id{table}_id列上有索引,就不需要添加foreign_key约束来加快查询速度。

+2

列名之后,公约是不一样的[FOREIGN KEY约束](https://en.wikipedia.org/wiki/Foreign_key)。 – spickermann

+0

哦对,我没有明白这一点。我正在更新我的答案 – Caillou

1

铁轨(或ActiveRecord的)只是各地的参赛作品简单的ORM在一个数据库。它不利用数据库提供的大多数功能。部分原因是因为他们想成为数据库不可知论者,并且许多更高级的功能都是DBM特有的。但也因为一些人认为把逻辑放入数据库是万恶之源。

这并不意味着一切都是邪恶的,但它应该小心使用。尤其是存储过程。这就是说,我相信,Rails中的外键约束和索引是未充分利用的。创建它们没有太多缺点(除了播种)。

例如,您可以对一对一关系使用唯一键约束来防止多条记录。 Rails默认不会这样做。你可以依靠的验证,但使用的DB是更安全的选择:

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

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

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

您可以结合两种:

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

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

如果你现在创建它实际上为你创建的索引和外键约束参照的轨道迁移:

~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 
相关问题