是否可以设计通用的多对多接合表?

时间:2018-03-17 04:41:11

标签: mysql database-design many-to-many

让我们说我想设计一个天真的应用程序,它有以下三个表:

basic

有两对多关系:

  1. 客户可能有许多喜欢的头像,许多客户可能会使用头像;
  2. 产品可能包含许多产品图像,许多产品可能会使用产品图像;
  3. 因此我们可以添加两个联结表来完成上述关系:

    junction-table

    customer_image表与product_image表非常相似,是否可以创建如下的通用联结表?

    enter image description here

    由于generic_map表将由不同的模型(客户,产品等)使用,我删除了外键约束。

    有什么建议吗?感谢。

2 个答案:

答案 0 :(得分:1)

为什么你想要这样做并不清楚。它为您为每个多对多关系创建一个单独的表有什么好处?

它还会产生许多不必要的复杂性。

约束

必须删除外键约束以使你的表工作的事实应该是一个强有力的线索,这是一个糟糕的策略。

重复

因此,如果您从image表格到generic_map.to_id进行联接并找到图像映射到from_id的给定值,例如1234,您如何知道值引用ID为1234的customer或ID为1234的product

通常,多对多映射表对引用每个实体的列对具有UNIQUE约束。但是在generic_map你可以有这样的约束吗?

如果customer 1234和product 1234都希望映射到同一张图片,该怎么办?您是否将映射行存储在generic_map表中两次?如果是这样,当您从customergeneric_map加入image时会发生什么?你会从联接中获得重复。

另外,如果仅customer 1234想要引用特定图像,但具有相同ID 1234的product不想要该图像,该怎么办?您如何明确product 1234应该加入generic_map表中的那一行?

所以你评论说:

  

我忘了在type中声明generic_table列,type列的类型为ENUM('customer', 'product')。通过此列,我可以知道generic.from_id值1234表示客户ID或产品ID。

但这导致另一个问题......

查询

您必须记住在运行的每个查询的额外type列上添加条件:

SELECT ...
FROM customer AS c
JOIN generic_map AS m ON c.id=m.from_id AND m.type='customer'
JOIN image AS i ON m.to_id

如果您(或团队中维护此代码的其他人)忘记包含此条件,那么您将获得我上面描述的奇怪效果。

性能

针对较小表的查询通常更快。但现在你可以保证有一张大桌子。

假设您有单独的表,您的customer_image表有10,000,000行。您的product_image表有1,000行。您应该担心,对产品图像的查询需要搜索10,001,000行而不是1,000行。索引可以提供帮助,但如果表格是分开的,那么性能会更好。

以上只是一些问题。他们像松散的线程一样解开。

帮自己一个忙 - 只需使用两个表,每个多对多关系一个表。它会让一切变得更轻松。

答案 1 :(得分:0)

可以为关系创建一个通用表,但是作为一个好的数据库,使用单独的表进行映射会更好。

如果要使用通用表进行映射,可以使用字段idcustomer_idimage_idproduct_id创建TinyDB tinyDB = new TinyDB(MyActivity.this);表。