使用一个“主要”值实现多对多

时间:2011-04-21 01:10:25

标签: sql ruby-on-rails postgresql activerecord

我有很多产品可以分为多个类别。

products: id, ...
products_categories: product_id, category_id
categories: id, ...

现在我想拥有许多产品,每个产品都有一个主类别,以及0个或更多个辅助类别。我可以想到两种在SQL中对此进行建模的方法。

  1. is_primary添加products_categories列 OR

  2. primary_category_id列添加到products

  3. 在纯SQL和/或ActiveRecord中实现此功能的最佳方法是什么?我正在使用PostgreSQL,因为它的价值。

4 个答案:

答案 0 :(得分:1)

我会选择第一个选项,除非我有充分的理由选择2(比如获得主要类别时额外加入的费用)

原因:您可能需要将主要类别添加到product_category表中(以便在查询中以统一且简单的方式使用它,例如获取产品的所有类别) 选项1避免重复主要类别因此更简单

答案 1 :(得分:1)

我会选择(1)。这样做的原因是,您的产品可以属于多个类别,关系属性(它的“主要”类别)属于定义关系的表。

我甚至会更进一步,建议不要标记字段'is_primary',而应该将字段标记为'association_type'。而不是仅添加位字段,使其成为整数字段,并定义所有关联类型。在您的情况下,只有两种关联类型 - 次要和主要。优点是这种设计更具可扩展性。如果明天要求您定义“主要”,“次要”和所有其他大学类别,此设计将能够处理它,而不必添加另一个字段来指定“辅助”字段。

答案 2 :(得分:1)

这实际上取决于您要完成的具体细节。以下是在决定什么对您最有利时要考虑的一些事项。其他答案已经解决了第一种情况,所以我将重点关注第二种情况。

如果你有primary_category_id

  • product中有一个字段告诉哪个category是主要字段,而不是在每个product_category中都有1的字段,这似乎更清晰尽管MR建议使用0听起来也很干净,但每行中都有association_type行?但是你有可能获得“第三级”类别吗?
  • 进入主要类别
  • 稍微容易一些
  • 很容易确保每件商品都有一个主要类别(只需填写字段NOT NULL
  • 自动强制产品可能只有一个主要类别
  • 您是否还应将主要类别插入products_categories
    • 这两个选项都没有强制执行。
    • 如果不这样做,查询所有类别
    • 会很尴尬
    • 如果你这样做,它仍然很容易查询,但没有额外的工作,没有什么可以保证主要类别也插入到另一个表中

如果您使用is_primary方法,则应以某种方式确保每个产品始终只有一个主要类别。

答案 3 :(得分:0)

每种方式的优点和缺点是什么?

选项1。我可以肯定产品的主要类别确实是其中的一个类别。但是可能存在确保产品不超过一个主要类别的问题。

选项2。这可以让我确保产品只有一个主要类别。但是,我似乎没有办法确保它是同一产品类别之一。

所以,我可能会使用表Products_PrimaryCategories来寻找第三个选项

Products_PrimaryCategories: product_id, category_id

它似乎与product_categories相同,但有一些额外的属性:

  • product_id有一个关联的唯一索引,确保每个产品只能有一个主要类别;

  • (product_id, category_id)是引用products_categories (product_id, category_id)的外键,确保产品的主要类别是类别之一(这意味着(product_id, category_id)应该是products_categories的主键。