【问题标题】:Implementing many-to-many with one "primary" value用一个“主要”值实现多对多
【发布时间】:2011-04-21 01:10:25
【问题描述】:

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

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

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

  1. is_primary 列添加到products_categories 或者

  2. primary_category_id 列添加到products

在纯 SQL 和/或 ActiveRecord 中实现此功能的最佳方法是什么?我正在使用 PostgreSQL,这是值得的。

【问题讨论】:

    标签: sql ruby-on-rails postgresql activerecord


    【解决方案1】:

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

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

    【讨论】:

      【解决方案2】:

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

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

      【讨论】:

        【解决方案3】:

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

        如果你有primary_category_id:

        • product 中有一个字段来告诉哪个category 是主要字段,这似乎比在每个product_category 中都有一个字段,其中1 在一行中,0 在每一行行,虽然 M.R. 使用 association_type 的建议听起来也很干净 - 但是你会有什么机会拥有“三级”类别?
        • 进入主要类别稍微容易一些
        • 很容易确保每个产品始终都有一个主要类别(只需输入字段NOT NULL
        • 它会自动强制产品只能有一个主要类别
        • 是否还应该将主要类别插入products_categories
          • 这两个选项均未强制执行。
          • 如果不这样做,查询所有类别会很尴尬
          • 如果这样做,查询仍然很容易,但无需额外工作,无法保证主类别也插入到其他表中

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

        【讨论】:

          【解决方案4】:

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

          选项 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 的主要类别键)。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2012-10-06
            • 2010-10-24
            • 1970-01-01
            • 2011-08-30
            • 1970-01-01
            • 1970-01-01
            • 2021-12-25
            • 2018-04-29
            相关资源
            最近更新 更多