【问题标题】:Add foreign keys to database in Rails app [closed]在 Rails 应用程序中向数据库添加外键 [关闭]
【发布时间】:2016-03-08 12:02:34
【问题描述】:

使用PostgreSQL,我知道Rails 不会在数据库中使用外键,而是通过Active Record Associations has_one、has_many.... 以及许多其他方式处理所有关系,而且我知道有像Foreigner 这样的宝石可以帮助解决这个,

但是将外键添加到数据库表中是否值得加快速度?为什么有人可能会关心添加它?

【问题讨论】:

    标签: ruby-on-rails ruby database postgresql


    【解决方案1】:

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

    database index 用于加快查询速度。

    它们看起来很相似,并且经常在相同的上下文中使用,但它们并不相同。


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

    add_foreign_key :posts, :users
    

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

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

    【讨论】:

    • 我认为您在这一点上是对的,数据完整性和一致性是 Rails 应用程序数据库中外键背后的主要原因。
    【解决方案2】:

    Rails(或 ActiveRecord)只是一个围绕数据库条目的简单 ORM。它没有利用数据库提供的大多数功能。部分原因是他们希望与 DB 无关,并且许多更高级的功能是 DBM 特定的。但也因为有些人认为将逻辑放入 DB 是万恶之源。

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

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

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

    您也可以利用外键约束自动让数据库删除依赖记录:

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

    您可以将两者结合起来:

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

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

    如果您现在使用引用创建 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
    

    【讨论】:

      【解决方案3】:

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

      文档:http://guides.rubyonrails.org/association_basics.html#the-belongs-to-association (寻找关键字“迁移”)

      编辑:

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

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

      【讨论】:

      • 遵循约定的列名与数据库中的FOREIGN KEY constraint不同。
      • 哦,对了,我没听懂。我正在更新我的答案
      猜你喜欢
      • 2015-12-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-12-08
      • 2019-01-23
      • 2013-04-21
      • 1970-01-01
      相关资源
      最近更新 更多