使用PostgreSQL
,我知道Rails不会在数据库中使用外键并通过Active Record Associations has_one,has_many ....和其他许多处理所有关系,我知道有像{{3这样的宝石可以帮助解决这个问题,
但是将外键添加到数据库表是否值得加速?为什么有人可能会想要添加它?
答案 0 :(得分:2)
我认为foreign key constraints是确保数据完整性和一致性的工具。
而database index用于加速查询。
它们看似相似,经常在相同的环境中使用,但它们并不相同。
顺便说一下,没有必要使用像Foreigner这样的宝石。从开箱即用的Rails 4.2开始支持外键。看看add_foreign_key
:
add_foreign_key :posts, :users
或者您可以使用foreign_key
和belongs_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}_id
和id
列上有索引,就不需要添加foreign_key约束来加速查询。