何时应该在Ruby on Rails数据库的表中使用连接表vs id

时间:2014-05-31 04:50:56

标签: mysql ruby-on-rails database jointable

所以,我和一位同事正在讨论如何为我们正在开发的网站设计数据库的一部分。我们都是相当新的数据库设计,并不能肯定我们哪个选项更好,所以我跳来提出想法,并获得最好的建议为什么一个比另一个更好或为什么他们可能可以互相比较

以使用为例,假设我们的数据库中有三个表如下。 Car_manufacturers,Car_models和Car_serialNumbers。每个Car_manufacturer都有许多Car_model,但每个Car_model只有一个Car_manufacturer。此外,每个Car_model都有许多Car_serialNumbers,但每个Car_serialNumber只有一个Car_model。这种关系创建了一个向下的树,其中Car_manufactuere是根,后跟Car_model和Car_serialNumber。

问题是使用mysql在RUby on Rails中实现这一点的最佳方法是什么。以下是我们争论的两种方式。

我的想法是主键是Car_manufacturer的id,它将作为外键存储在Car_model表中。然后在Car_manufacturer和Car_model之间分别创建一个has_many到belongs_to关系。从Car_model到Car_serialNumber也是如此。我相信这是最好的,因为seach child只属于它的一个父节点,单个foreign_key很简单,并且在Ruby On Rails中很容易设置和管理这种关系。

我的同事的想法是我们使用连接表来处理所有事情。因此,Car_manufactuere和Car_model将指向一个完全独立的表,该表可以容纳两个键。然后,该表充当两者之间的代理。对Car_model和Car_serialNumber也是如此。

因此,正如我所看到的,这会创建不必要的额外数据。为什么只需将信息存储在各自的表中,就可以用较少的数据完成关系,从而创建连接表。此外,如果我正确理解has_many和belongs_to关系,那么联接表不是它们的目的。加入表最适合has_many到has_many realationships。两种方式都可以解决同样的问题,但我相信我的解决方案更简单,更简单的代码创建更少的错误,这是我坚实设计的动力。

那么,这是一个更好的效率和简单设计?哪个会提供最大的利益?我在网上看过很多资料,但似乎都没有回答这个问题。对问题的任何输入或对有用资源的链接都会有很大的吸引力。

2 个答案:

答案 0 :(得分:1)

无法让自己阅读所有文字,所以这就是我要做的事情:


Use an STI

#app/models/car.rb
Class Car < ActiveRecord::Base
   #fields - id, type, manufacturer_id, other, info, created_at, updated_at
   has_many :serials
   belongs_to :manufacturer
end

#app/models/cars/aventador.rb
Class Aventador < Car
   before_create :set_details

   def set_details
      self.manufacturer = Manufacturer.find_by name: "Lamborghini"
      self.site = "http://www.lamborghini.com/en/models/aventador-lp-700-4/overview/"
   end
end

#app/models/serial.rb
Class Serial < ActiveRecord::Base
   fields - id | car_id | serial | created_at | updated_at
   belongs_to :car
end

#app/models/manufacturer.rb
Class Manufacturer < ActiveRecord::Base
   fields - id | name | founded_at | created_at | updated_at
   has_many :cars
end

这将允许您致电:

aventadors = Aventador.all
aventadors.each do |lambo|
   #-> lambo.serials - shows all serials for the Aventadors in your fleet!
   #-> lambo.manufacturer.name - shows the manufacturer's name
end

这方面的缺点虽然非常酷,但您必须为每个车型定义一个模型,并在每个车型中手动定义制造商。


无聊的方式

您可以将其设置为“无聊”,如下所示:

#app/models/car.rb
Class Car < ActiveRecord::Base
   #fields - id | manufacturer_id | other | items | created_at | updated_at
   has_many :serials
   belongs_to: manufacturer
end

#app/models/serial.rb
Class Serial < ActiveRecord::Base
   #fields - id | car_id | other | items | created_at | updated_at
   belongs_to :car
end

#app/models/manufacturers.rb
Class Manufacturer < ActiveRecord::Base
   #fields - id | other | items | created_at | updated_at
   has_many :cars
end

答案 1 :(得分:1)

这是一对多(您的想法)和多对多(联接表)关系之间的差异。您的数据看起来像是一对多的层次结构,因此在这种情况下,您的想法的实现更简单,更易于维护。