【问题标题】:Creating a relationship between three tables创建三个表之间的关系
【发布时间】:2013-07-01 08:57:22
【问题描述】:

我可以想到很多方法来解决这个问题,但我想知道这里的最佳做法是什么:

我有三张桌子。产品、价目表和价格。

一个产品可以属于多个价目表。

一个价目表可以属于许多产品。

这是一个多对多的关系,据我所知需要一个连接表 (pricelist_products)。哪个效果很好。

现在,价目表中的一种产品可以有多个价格。产品只有在价格表中才会被赋予价格。

我在这里想到的是使用联结表 'pricelist_products' 中的 ID 作为价格表中的外键,但这感觉真的...... hacky?

鱼腥味的例子:

产品 1 - 钓鱼竿。

价目表 A - 渔夫。

价格表 B - 钓鱼店。

价目表 A,产品 1,价格 1: (每月还款选项1(无押金))

价目表 A,产品 1,价格 2: (每月还款方式二(有押金))

价目表 A,产品 1,价格 3: (按季度还款)

价目表 B,产品 1,价格 1: (按季度还款)

【问题讨论】:

  • 你为什么觉得它很hacky?这是正确的模型。
  • 如果你的 id 字段不全称为 id,编码时会容易得多。将它们命名为 product_id、price_id、pricelist_id、pricelist_product_id。它使直观地验证您的 SQL 变得更加容易。
  • 命名字段只是一个约定的编码约定和/或个人偏好的问题。 MySQL 具有非常方便的 AS 别名技术。我个人的偏好是不要对字段使用长而复杂的名称,即我会将我的字段命名为 Mason8r
  • 我不会说价格是价格表的正确词。我的意思是价格和数值。也许,“支付计划”

标签: mysql sql database database-design theory


【解决方案1】:

如果您不会在其他任何地方使用产品和价目表之间的关系,但对于价格,那么另一种设计是这样的:

-表格产品的字段:id,others

-表格价格表,字段:id,其他

-带有字段的表格价格:id(自动增量),product_id,pricelist_id,price

您将在 product_id、pricelist_id 这对字段上定义索引(不是唯一的)

【讨论】:

  • 现在我看到你用图像编辑了。所以我建议将所有其他字段从 price 放置到 pricelist_product 并简单地将 pricelist_product 重命名为 price。并再次在 (product_id, pricelist_id) 上定义一个索引
  • 谢谢 Nedret,很高兴从另一个角度看到它。我将用两种方式制作原型。
【解决方案2】:

我在这里想到的是使用联结表 'pricelist_products' 中的 ID 作为价格表中的外键,但这感觉真的...... hacky?

也许这里的问题只是一种观点。联结表的目的是在多对多关系中唯一地定义每个组合(最初:pricelistproduct)。这可以在联结表中单独使用字段product_idpricelist_id 来实现,而无需代理键id

当然,如果您使用PRIMARY KEY (product_id, pricelist_id) 定义了您的联结表,那么在考虑price 时,该表将缺乏唯一定义组合的能力。因此,您将第三个id 添加到联结表中。在仅定义两个表之间的关系时,您似乎将此字段视为必要的代理键。但是,由于此字段的实际用途与第三个表相关,因此您可以将其命名为 price_id,将您的联结表命名为 pricelist_product_price,并在所有三个字段上定义主键(例如)。这更清楚地展示了每个领域的目的,因此在实践中可能不会觉得“hacky”。​​

我不知道这是否是数据库设计的最佳实践,但请记住,没有理由必须对每个数据库进行完全规范化。您需要具有合理的灵活性和可扩展性的良好性能(这对于休闲博客来说可能是一回事,而对于小型企业来说则是另一回事),而这通常可以通过某种程度的非规范化设计来实现。

编辑添加: 好的,我忘了提到另一项更改,它属于“良好”设计或最佳实践。在您的图片中,price 表中有两个 ID 字段,其中一个就足够了。正如@Gilbert Le Blanc 指出的那样,您应该尽量避免模糊的字段名称,例如拥有多个 id 字段,即使它们位于不同的表中。这将帮助您了解字段的实用性、识别自然键并消除冗余。

【讨论】:

  • 我需要 15 个代表来投票,不过谢谢你,这很有帮助。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-07-16
  • 2017-07-18
  • 2012-07-11
  • 1970-01-01
  • 1970-01-01
  • 2019-08-26
  • 1970-01-01
相关资源
最近更新 更多