「用戶標籤」在資料庫設計時應該如何存儲?

業務邏輯是這樣的:

用戶可以給自己貼標籤,以供他人搜索。比如我給自己貼上「90後 程序員」的標籤,那麼別人就能通過「90後」或者「程序員」搜到我。

用戶最多可以給自己貼10個標籤。標籤可以隨時更新。

方案一:在User表裡設置一個tags欄位,裡面存的是「90後,程序員」這樣的字元串,用逗號分隔不同標籤。缺點:不便於搜索,建立索引的話會很低效,因為「90後,程序員」和「程序員,90後」被認為是不同的。

方案二:在User表裡設置10個tag_n欄位(n=1,2,3...10),每個欄位存一個標籤。缺點:不利於Update。比如我現在把我的標籤改為「程序員,90後,帥哥」,那麼我要逐個檢查「程序員」、「90後」和「帥哥」是否已存在,不存在才能添加。

不知道有什麼好方法。

我在問問題的時候想到可以先給標籤排序在存到資料庫里。

注1:存tag的id而不是存tag的內容這一點已經採用了,我在問題里直接用tag內容是為了表述方面。

注2:我使用的是關係型資料庫。


這應該是一個多對多的問題。

對於小型系統,我的設計方案通常是這樣

user表

=====================

userId userName

=====================

1 test

2 test2

...

tag表

=====================

tagId tagName

=====================

1 tag

2 tag2

...

relation表

=====================

relationId userId tagId

=====================

1 1 1

2 1 2

...

insert update 之類的應該都很簡單,不是問題

查詢可能有點麻煩,需要用到聯合查詢

語句一般是這樣

SELECT userId, userName FROM user u

INNER JOIN relation r ON u.userId=r.userId

WHERE r.tagId = 1

這樣就查出了所有tagId為1的用戶。

索引對這個方案可能效果不是很明顯,數據量小的時候,索引的提升不明顯,數據量大的時候,索引對聯合查詢起不到什麼提升作用。

其實你的方案1不失為一種可行方案,特別是數據量驚人的情況,你可以採用方案1配合NoSQL的方式。


方案一明顯是不行的,也浪費空間。

方案二有點正確的味道了,但是仍然不對。

全站的標籤應該在另外一個表裡面,標籤文字是unique的,對應一個數字id

用戶表裡面關於用戶標籤存放的是應該是這些數字id,而且沒必要設置10個欄位,而應該是一個欄位,以字元串形式存放,逗號分割的id文本就好。

用戶添加標籤:

檢查全站是否已有該標籤,沒有的話添加到標籤的表,得到標籤對應id,追加到用戶表的相應欄位字串末尾,當然你還要檢查標籤個數限制什麼的都是可以的。

用戶刪除標籤:

查找該標籤對應ID,隨便什麼方式在對應用戶對應欄位去掉改id值,文本替換就行

用戶修改標籤:

刪除+添加


數據量小,用mongodb,建個帶索引的array列,裡面放標籤。

數據量大,用elasticsearch,標籤就是關鍵詞,按搜索引擎的套路走。

標籤變更生效有一點延遲,不過從業務角度看,這應該不是問題。


我想簡單說下我的觀點。

對於標籤這個問題,無論是用戶的標籤,還是內容的標籤,這其實都屬於搜索的範疇。

我認為都應該採用倒排表(inverted index)的數據結構來存儲。

對於標籤的數據結構,無論存儲在文件中還是資料庫中,格式為:

label1 -&> [ id1, id2, id3, .... idN]

label2 -&> [ id8, id9, id10, .... idM]

這樣存儲的好處是,當用戶搜索標籤時,可以迅速得到所有id集合,然後做交集操作即可。

同時,每個用戶user表,可以設一個tags欄位,裡面存所有label。當想查看某個用戶的標籤時,也可以迅速獲取。


標籤服務實現漫談


標籤庫??樓上推薦的都是什麼啊。。Bitmap演算法啊=。=


hbase簡單搞定


不建議過多考慮標籤庫的更新與對象標籤記錄的同步問題,原因有二:

  1. 標籤庫可以理解成一種模版,為對象添加標籤後,它們之間不需要強約束關係(或者說,這種場景使用極少)。

  2. 基於標籤的統計和分析在大數據處理技術蓬勃發展的現在不是難點,而且類似統計實時性要求不高,完全可以離線計算得到。


參考Django ManyToManyField


推薦閱讀:

關於InnoDB中mvcc和覆蓋索引查詢的困惑?
sql server怎麼在存儲過程中模糊查詢?
女生做web前端還是資料庫運維?
資料庫工程師需要具備什麼樣的能力和素質?
資料庫建表時一定要設置外鍵約束關係嗎?

TAG:資料庫 | 資料庫設計 |