使用一个“主”实施多对多价值

发布于 2024-11-02 14:32:21 字数 464 浏览 1 评论 0原文

我有很多产品,每个产品都可以属于多个类别。

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

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

  1. is_primary 列添加到 products_categories 或者

  2. products 添加 primary_category_id

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

I have many products that can each be in many categories.

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

Now I want to have many products, each with one master category, and 0 or more secondary categories. I can think of two ways to model this in SQL.

  1. Add an is_primary column to products_categories
    OR

  2. Add a primary_category_id column to products

What is the best way to implement this in pure SQL and/or ActiveRecord? I'm using PostgreSQL, for what it's worth.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

那小子欠揍 2024-11-09 14:32:21

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

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

I would go with the first option unless I have a good reason for choosing 2 (like the cost of an extra join when getting the primary category)

reason: you probably need to add the primary category to product_category table anyway (in order to use it in a uniform and simple way in queries like getting all categories for a product)
option 1 avoids duplicating primary category thus simpler

默嘫て 2024-11-09 14:32:21

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

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

I would go with option (1). The reason for this is since your products can belong to more than one category, the relationship attribute (that its a 'primary' category) belongs in the table that defines the relationship.

I would even go further and suggest that instead of labeling the field 'is_primary', you should have the field labeled as 'association_type'. And instead of just adding a bit field, make it an integer field, and have all the association types defined. In your case today, there are only two association types - secondary and primary. The advantage is that this design is much more scalable. If tomorrow, you are asked to define a 'primary', a 'secondary' and all other tertiary categories, this design will be able to handle it, instead of having to add another field to designate the 'secondary' field.

凝望流年 2024-11-09 14:32:21

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

如果您有 primary_category_id

  • product 中有一个字段来告诉哪个 category 是主要类别,这似乎比在尽管 MR 建议使用 association_type,但每行中具有 1 且每隔一行具有 0product_category > 听起来也很干净——但是你有“第三级”类别的机会有多大?
  • 到达主要类别稍微容易一些
  • 很容易确保每个产品始终都有一个主要类别(只需使字段 NOT NULL
  • 它会自动强制产品只能有一个主要类别
  • 如果您还将主要类别插入products_categories
    • 这两个选项均不强制执行。
    • 如果不这样做,查询所有类别就很尴尬
    • 如果这样做,查询仍然很容易,但无需额外工作,无法保证主类别也插入到其他表中

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

It really depends on the exact details of what you're trying to accomplish. Here are some of the things to consider while deciding what's best for you. Other answers already tackled the first case, so I'm going to focus on the second one.

If you have primary_category_id:

  • It seems cleaner to have one field in product that tells which category is the primary one, than to have a field in every product_category which has 1 in one row and 0 in every other row, although the suggestion by M.R. to use association_type sounds clean too - but what's the chance you're going to have "tertiary" categories?
  • It's slightly easier to get to the primary category
  • It's easy to ensure every product always has a primary category (just make the field NOT NULL)
  • It automatically enforces that a product may only have one primary category
  • Should you also insert the primary category to products_categories?
    • Neither option is enforced.
    • If you don't, it's awkward to query all the categories
    • If you do, it's still easy to query, but without additional work, nothing guarantees the primary category is also inserted in the other table

If you use the is_primary method, you should somehow ensure that every product always has exactly one primary category.

拔了角的鹿 2024-11-09 14:32:21

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

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

What are each way's pros and cons?

Option 1. I can be sure that the primary category for a product is indeed one of its categories. But there may be a problem of ensuring that a product has no more than one primary category.

Option 2. This lets me make sure that a product has only one primary category. But then I don't seem to have a way to make sure that it's one of this same product's categories.

So, I would probably go for a third option, using a table Products_PrimaryCategories:

Products_PrimaryCategories: product_id, category_id

It seems the same as product_categories, but has some additional properties:

  • product_id has an associated unique index, making sure you can only have one primary category for each product;

  • (product_id, category_id) is a foreign key referencing products_categories (product_id, category_id) ensuring that a product's primary category is one of its categories (which implies that (product_id, category_id) should be products_categories's primary key).

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文