鍍金池/ 問答/人工智能  數(shù)據(jù)庫/ 數(shù)據(jù)庫: 多對多關(guān)系哪種表示形式更優(yōu)? 全面?

數(shù)據(jù)庫: 多對多關(guān)系哪種表示形式更優(yōu)? 全面?

背景:
我要為我們的產(chǎn)品添加打標簽的功能, 一個產(chǎn)品可以有多個標簽, 而且每個標簽可以被多個產(chǎn)品使用, 也就是所謂的多對多關(guān)系.
具體化:
我們有1000萬個產(chǎn)品Product, 管理員定義了20個標簽Tag, 我們要給這1000萬個產(chǎn)品打上標簽(1個或多個), 為此我們建立了一個Product表和一個Tag表.
問題:
怎么表示這個多對多關(guān)系? 優(yōu)化方案?性能?
我們第一個想法:
中間表: ProductTag連接Product和Tag, 形成多對多關(guān)系. 但這樣每次需要遍歷ProductTag表和從Tag表獲取標簽描述信息, 因為查看標簽遠遠大于設(shè)置標簽的次數(shù), 那這樣豈不是很浪費效率?
于是第二個想法:
緩存字段, 在Product里面定義一個數(shù)組類型字段tags, 里面存儲Tag對象的id, 那這樣就可以查看的時候,直接根據(jù)tags獲取Tag對象數(shù)組,然后獲取每個標簽的描述信息. 但是問題來了, 有天管理員從Tag表刪除了一個標簽對象, 那么我們要遍歷所有的Product, 從tags刪除掉這個標簽的id. oh my god!!!
于是第三個想法:
我們還是用第二個想法, 只是管理員刪除一個標簽對象時, 我們不做任何操作, 而是在查看產(chǎn)品的標簽數(shù)據(jù)時, 檢查tags里面的標簽是否有效(查詢Tag表). 那么問題又來了, 查看產(chǎn)品次數(shù)遠比刪除標簽的次數(shù)多, 豈不是又浪費效率性能?
有沒有更好的方法?或者優(yōu)化方案?
望解答!感謝~

回答
編輯回答
毀憶

可以先擴展一下『第二個想法』,Product存tags字段,自然Tag也能存products字段存放這個標簽有哪些product,你要刪某個tag,把這個tag的products拿出來遍歷一部分即可,也就是這份『關(guān)系』同時在Product和Tag冗余一份。但是這樣做要不了多久products字段非常大,實操下來肯定很慢。

那么結(jié)合『第一個想法』,不要products字段,只要tags字段,再加上做了索引的ProductTag中間表,平時不用ProductTag,一旦要刪tag,從ProductTag表讀,然后一個個去處理Product的tags字段。

希望能幫助到你。

2017年3月2日 12:57