Mysql
MySQL - 多對多關係,或一對多與附加列
我們的產品包含一些約束,使我們考慮哪種表設計將產生最佳性能。
我們的型號:
- 包含 id、body、難度和標籤等欄位的 問題表。
- 每個問題最多可以有五個不同的標籤。
- 標籤表,其中包含 id 和標籤名稱等欄位。
問題表的讀取次數將明顯多於寫入次數。
我們考慮了兩種設計方案:
- 多對多關係,我們將有以下表格
- 問題 - 標籤問題 - 標籤
- 一對多關係,我們將有以下表格
- 問題標籤
在此選項中,問題表將包含五個標籤列(TagA、TagB 等)
“閱讀”查詢將主要按標籤或標籤獲取問題。
基本上你只能使用
Question - TagsQuestion - Tags
使用橋接表,如果為多個問題設置一個標籤。
如果您有很多問題,它還可以節省一些空間。
第二個選項有一個問題,如果你想顯示所有標籤,你需要五個內部連接,每個標籤一個,而你可以用兩個連接進行相同的查詢,第一個選項..
總體而言,使用橋接表的第一個選項是更靈活且佔用空間的選項。
“標籤”本質上是真還是假?它們是預定義的嗎?(也就是說,您將來不太可能添加新標誌。)如果是這樣,儲存它們的一種緊湊方法是通過
CREATE TABLE ... tags SET('approved', 'sold', 'built', 'answered', 'lost') NOT NULL
有多種功能可用於測試標誌,尤其是
FIND_IN_SET()
.(如果您給我們一些可能的標籤名稱,將會有所幫助。)
或者不是多對多
上次我實現“標籤”功能時,我有(使用你的術語):
CREATE TABLE tags ( question_id MEDIUMINT UNSIGNED NOT NULL, tag VARCHAR(55) NOT NULL, PRIMARY KEY(question_id, tag), INDEX(tag, question_id) ) ENGINE=InnoDB;
PK 使得查找給定問題的標籤變得高效;二級索引使查找具有特定標籤的問題變得有效。這可以很好地擴展並且比 3 表方法更簡單。無限數量的標籤是可能的;缺點是沒有發現拼寫錯誤。