【问题标题】:How to store City and Neighborhood associated with a Restaurant?如何存储与餐厅关联的城市和社区?
【发布时间】:2013-05-06 21:04:07
【问题描述】:

我有一份餐馆清单。每个都位于特定城市的社区/地区。

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

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

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

采用一种或另一种方法的优点或缺点是什么,我应该选择什么?

谢谢

【问题讨论】:

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


    【解决方案1】:

    关系

    第二组关系是最合适的。正如 Mik_Die 所提到的,主要原因是它被规范化了。如果您要查看第一个示例的 DB 架构,您会得到类似以下的内容

    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 通过:through 选项为has_many 提供了出色的扩展。

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

    你的模型看起来像这样

    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
    

    然后你可以做这样的事情

    @neighborhood.restaurants # => Returns all restaurants for that neighborhood
    @city.restaurants # => Returns all restaurants from each of the neighborhoods belonging to the city
    

    【讨论】:

      【解决方案2】:

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

      【讨论】:

      • 为什么第一个版本不规范化?
      【解决方案3】:

      第二个版本比第一个更好,因为您只需要记录一次关联。在第一种情况下,您是在为一家根本不需要的餐厅节省城市和社区的成本……

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2013-08-21
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-11-18
        • 1970-01-01
        • 2013-04-13
        相关资源
        最近更新 更多