MySQL 中多对多关系的最佳模式是什么?

时间:2021-01-05 07:39:30

标签: mysql sql database-design

我需要设计一个数据库架构。我的数据如下:

<块引用>

产品 ID(主键)、产品名称(字符串)、产品类型(字符串)、商品数量(INT)、标签(字符串数组)

我的要求:

<块引用>
  1. 我需要经常根据标签查询产品。这是一种多对多关系 - 每个产品 ID 可以有多个标签,每个标签可以有多个产品 ID。
  2. 查询如下:
Select p.product_name 
from PRODUCTS as p 
JOIN PRODUCT_TAG as pt on p.id = pt.product_id 
JOIN TAGS as t on t.id = pt.tag_id
where t.tag = 'tag_name';

Select item_count
from PRODUCTS
where product_id = id;

Update PRODUCTS set item_count = count
where product_id = id;

这是我想拥有的架构:

PRODUCTS

+----+--------------+-------+------------+
| id | product_name | type  | item_count |
+----+--------------+-------+------------+
|  1 | abc          | type1 |          1 |
|  2 | def          | type2 |          1 |
+----+--------------+-------+------------+

TAGS

+----+------+
| id | tag  |
+----+------+
|  1 | tag1 |
|  2 | tag2 |
+----+------+

PRODUCT_TAG

+------------+--------+
| product_id | tag_id |
+------------+--------+
|  1         |      1 |
|  1         |      2 |
|  2         |      1 |
|  2         |      2 |
+------------+--------+

现在,我知道这个模式不是实现我所需要的最佳方式。它也非常占用空间,因为 PRODUCT_TAG 表会很大。此外,如果 PRODUCTS 表的行数几乎是 PRODUCT_TAG 表的 10%,那么对如此庞大的表进行连接将不会非常有效。我对 MySQL 数据库不是很熟悉。那么,最好的方法是什么?

感谢任何帮助。提前致谢!

2 个答案:

答案 0 :(得分:1)

使用连接表或桥接表(如您在 PRODUCT_TAG 表中提到的)是可行的方法。

以这种方式拥有我们的数据结构,可以更轻松地在表之间添加更多关系并更新您的产品和标签,而不会影响它们之间的关系。

答案 1 :(得分:1)

您可以通过四种方式连续存储多个标签:

  • 在多个列中,每个标签有一个单独的列。
  • 在一个分隔列表中。
  • 一套。
  • 作为 JSON。

前两个是坏主意。他们不允许:

  • 验证标签没有重复。
  • 检查两个实体是否具有相同的标签。

每个也有其自身的局限性。例如:

  • 单独的列限制了标签的数量。
  • 逗号分隔的列表不允许外键关系验证标签。

一组将标签限制为 64 个值。它们也可能相当混乱,因为它们在 MySQL 中不经常使用——并且在其他数据库中不受支持。这些值实际上是位,因此有一个技巧可以将它们作为字符串处理。我认为它们是一种黑客行为,但接受其他人认为它们在某些情况下很有用。

JSON 确实也有一些缺点,但对于多个值更容易接受。

但是,单独的联结表是一种行之有效的方法,可以满足您的需求。这样做很容易:

  • 添加和删除标签。
  • 验证分配的标签。
  • 防止产品上出现重复标签。
  • 查找特定产品上的标签。
  • 查找特定标签上的产品。
  • 等等。

如果性能是一个问题,那么索引通常可以解决问题。

在某些情况下,替代方案可能是合适的,但这些情况非常罕见。联结表解决方案更受欢迎。

相关问题