如何设计此rails数据库关系?

时间:2012-05-17 18:37:52

标签: ruby-on-rails ruby-on-rails-3 database-design many-to-many

好的,我有用户和公司。我有95%的用户会有一个且只有一个公司,所以我想做一对一。

用户表

create_table "users"
  string   "email",
  string   "first_name"
  string   "last_name"
  string   "phone_number"
  integer  "company_id"

但问题是有些管理员需要与系统中的多家公司和少数几家公司相关联。

因此,由于多对多的关系,我假设了一个连接表

加入表

"company_users"
  t.integer  "company_id"
  t.integer  "user_id"

但我必须经常评估用户公司,以便我能够轻松访问公司,并且不愿为5%的用户提供联接表。有什么想法吗?

4 个答案:

答案 0 :(得分:3)

除非您遗漏有多家公司的管理员数据,否则无法使用链接表。我建议您跟踪多对多和跟踪主要公司。

 class User
   belongs_to :primary_company, :class_name => Company
   has_many :company_users
   has_many :companies, :through => :company_users
 end

答案 1 :(得分:2)

不幸的是,即使系统中只有一个用户拥有多个公司,它也会变成多对多。

  1. 您可以要求用户有两条记录,每个公司一条记录,但这似乎并不理想。
  2. 您可以在公司用户身上放置2个外键,并使用不同的外键声明belongs_to :company, foreign_key: 'company1_id'两次。 不理想,但可以工作。
  3. 您可以使用支持数组的数据库并拥有一组company_ids。但这并不适用于ActiveRecord。但是,如果使用MongoDB是一个选项,Mongoid对此有很好的支持。
  4. 最有可能的是,你只需要一个连接表。我会考虑在那里为角色(管理员,员工等)添加另一个字段并调用模型Position。然后是用户has_many :positionshas_many :companies, through: :positions。如果这会导致大量的连接,你会想找到一种方法来缓存它。在Rails中缓存实际上非常简单。
  5. Rails Caching
    Low-level caching in Rails

答案 2 :(得分:0)

你可以反规范化。

添加布尔标记“only_1_company”。

使用触发器维护它。

答案 3 :(得分:0)

我重新阅读了答案,现在觉得你的问题在

"我希望能够轻松访问公司,并且不愿为5%的用户提供联接表。"

你讨厌什么'这个事实?如何只有5%'实际上影响应用程序架构或性能或可用性?

专注于为您的用户显示的问题。如果他们发现ui令人困惑或太慢,那么就要根据这个问题开展工作。

试图消除可能的'未来的性能问题通常被认为是对时间的不良使用。到那时,应用程序可能会发生很大变化。此外,解决性能可能意味着非规范化等方法,在确定确切问题之前,您绝对不想使用此类方法。

此外,数据库通过连接表查找记录非常有效,所以我再也不担心效率低下,除非它们现在导致实际问题。