2016-03-08 130 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 
相關問題