簡體   English   中英

MySQL 中多對多關系的最佳模式是什么?

[英]What is the best schema for a many-to-many relationship in MySQL?

我需要設計一個數據庫模式。 我的數據如下:

產品 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 數據庫不是很熟悉。 那么,最好的方法是什么?

任何幫助表示贊賞。 提前致謝!

使用連接表或橋接表(正如您在 PRODUCT_TAG 表中提到的)是 go 的方法。

以這種方式擁有我們的數據結構可以更輕松地在表之間添加更多關系並更新您的產品和標簽,而不會影響它們之間的關系。

有四種方法可以連續存儲多個標簽:

  • 在多個列中,每個標簽有一個單獨的列。
  • 在分隔列表中。
  • 一套。
  • 作為 JSON。

前兩個只是壞主意。 他們不允許:

  • 驗證標簽不重復。
  • 檢查兩個實體是否具有相同的標簽。

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

  • 單獨的列限制標簽的數量。
  • 逗號分隔的列表不允許外鍵關系驗證標簽。

一組將標簽限制為 64 個值。 它們也可能相當混亂,因為它們在 MySQL 中不經常使用 - 並且在其他數據庫中不受支持。 這些值實際上是位,因此有一個技巧可以將它們作為字符串處理。 我認為它們是一種 hack,但接受其他人發現它們在某些情況下有用。

JSON 也確實存在一些這些缺點,但對於多個值來說更容易接受。

但是,一個單獨的聯結表是一種行之有效的方法來做你想做的事。 它可以很容易地:

  • 添加和刪除標簽。
  • 驗證分配的標簽。
  • 防止產品上出現重復標簽。
  • 查找特定產品上的標簽。
  • 查找特定標簽上的產品。
  • 等等。

如果性能是一個問題,那么索引通常可以解決問題。

在某些情況下,替代方案可能是合適的,但這些情況非常罕見。 接線表解決方案更受歡迎。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM