在三个表之间创建关系

时间:2013-07-03 15:19:07

标签: mysql sql database database-design theory

我可以通过多种方式一起解决这个问题,但我想知道最佳做法是什么:

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

一种产品可以属于许多价格表。

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

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

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

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

ER Diagram

可疑的例子:

产品1 - 钓鱼竿。

价目表A - 渔民。

价目表B - Fishingshop。

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

价目表A,产品1,价格2: (每月还款选项2(有存款))

价目表A,产品1,价格3: (四分之一还款)

价目表B,产品1,价格1: (四分之一还款)

2 个答案:

答案 0 :(得分:1)

  

我在这里想到的是使用联结表'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字段,即使它们位于不同的表中。这将帮助您查看字段的效用,识别自然键并消除冗余。

答案 1 :(得分:0)

如果您不在其他任何地方使用产品和价格表之间的关系,而是价格,那么替代设计是这样的:

- 带有字段的表格产品:id,其他

- 带有字段的表格价格表:id,其他

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

你要在一对字段product_id,pricelist_id

上定义索引(不唯一)