如何存储与餐厅相关的城市和社区?

时间:2013-05-06 11:25:20

标签: ruby-on-rails database-design model

我有餐馆列表。每个人都位于特定城市的社区/区域。

我如何将餐馆与社区和城市联系起来?我想做什么:

Restaurant (belongs_to) -> Neighborhood
Restaurant (belongs_to) -> City

Restaurant (belongs_to) -> Neighborhood
Neighborhood (belongs_to) -> City

采取一种或另一种方法有什么优势或劣势,我应该选择什么?

由于

3 个答案:

答案 0 :(得分:3)

关系

第二组关系是最合适的。正如Mik_Die所提到的那样,主要原因是它已经正常化了。如果你要查看第一个例子的数据库模式,你会得到类似下面的内容

Restaurant (belongs_to) -> Neighborhood
Restaurant (belongs_to) -> City

Table: Restaurant
Column          |  Type       | 
---------------------------------------------
ID              |  Integer    |  Primary Key
name            |  String     |
neighborhood_id |  Integer    |  Foreign Key
city_id*        |  Integer    |  Foreign Key

Table: Neighborhood 
Column          |  Type       | 
---------------------------------------------
ID              |  Integer    |  Primary Key
name            |  String     |
city_id*        |  Integer    |  Foreign Key

Table: City 
Column          |  Type       | 
---------------------------------------------
ID              |  Integer    |  Primary Key
name            |  String     |

如果你查看我在旁边放一个星号的列,你会看到它在两个不同的表中重复,这是你在规范数据库时要避免的。

第二个架构几乎完全相同。您只需从Restaurant中删除city_id列。

Restaurant (belongs_to) -> Neighborhood
Neighborhood (belongs_to) -> City

Table: Restaurant
Column          |  Type       | 
---------------------------------------------
ID              |  Integer    |  Primary Key
name            |  String     |
neighborhood_id |  Integer    |  Foreign Key

Rails进来的地方

你的帖子被标记为Ruby on Rails,所以我认为讨论Rails如何看待这种关系很重要。您熟悉belongs_tohas_many关联。 Rails使用has_many选项为:through提供了出色的扩展。

我将假设您有兴趣将City存储在Restaurant餐桌中,因为您希望能够找到属于整个城市的所有餐厅。 :through的{​​{1}}选项允许该功能。

您的模型看起来像这样

has_many

然后你可以做这样的事情

class Restaurant < ActiveRecord::Base
  belongs_to :neighborhood
end

class Neighborhood < ActiveRecord::Base
  has_many :restaurants
  belongs_to :city
end

class City < ActiveRecord::Base
  has_many :neighborhoods
  has_many :restaurants, through: :neighborhoods
end

答案 1 :(得分:0)

在SQL数据库中,您应该规范化数据,因此第二种变体更合适。

答案 2 :(得分:0)

第二个版本比第一个版本更好,因为您只需要记录一次关联。在第一种情况下,你正在冗余地试图为一个根本不需要的餐馆保存城市和社区......