————————————————————————————————
Tag已經(jīng)成為Blog的一個(gè)事實(shí)標(biāo)準(zhǔn)之一,但是對(duì)于Tag的設(shè)計(jì)和實(shí)現(xiàn)方面很少找到相關(guān)資料:( 1.Tag是否需要單獨(dú)建表統(tǒng)計(jì)管理?那么增加、更新和刪除如何處理? 一種是用一個(gè)tag表和一個(gè)tag與其它表的關(guān)聯(lián)表來(lái)實(shí)現(xiàn),實(shí)現(xiàn)方式稍復(fù)雜些,你要記錄關(guān)聯(lián)的類型和ID。增加刪除就是處理這個(gè)關(guān)聯(lián)的表,更新可以分解為增加和刪除。 另一種是利用類似lucene的引擎,把tag丟進(jìn)去就可以了,實(shí)際上我沒用過它,不過簡(jiǎn)單測(cè)試過在rails項(xiàng)目里用ferret,它沒有中文分詞,搜索中文不太好用,但對(duì)于tag正合適,只要用一個(gè)字段把tag用空格分開再放進(jìn)去,只索引這一個(gè)字段。增加、刪除、更新其實(shí)只需要更新tags字段,ferret索引也更新一下就可以了。 關(guān)聯(lián)性是個(gè)復(fù)雜點(diǎn)的問題,以前問了別人一個(gè)SQL語(yǔ)句,不過測(cè)試性能一般。沒想到好主意,不過暫時(shí)也用不上它。 |
1.使用數(shù)據(jù)庫(kù)來(lái)存儲(chǔ),總覺得很難處理,但是方便統(tǒng)計(jì)和檢索,再更新上效率低下,另外但數(shù)據(jù)量非常大的時(shí)候,性能會(huì)下降很快。
2.使用Lucene是一個(gè)非常好的建議,但是我希望對(duì)Tag的使用上做不少細(xì)化的工作,如“Java”這個(gè)Tag在我的博客、我所在的圈子、網(wǎng)站等各級(jí)的統(tǒng)計(jì),不知道Lucence是否支持?
3.JavaEye使用了Tag技術(shù),不知道如何實(shí)現(xiàn)的?
_____________________________________________________________________________
1.使用數(shù)據(jù)庫(kù)來(lái)存儲(chǔ),總覺得很難處理,但是方便統(tǒng)計(jì)和檢索,再更新上效率低下,另外但數(shù)據(jù)量非常大的時(shí)候,性能會(huì)下降很快。
2.使用Lucene是一個(gè)非常好的建議,但是我希望對(duì)Tag的使用上做不少細(xì)化的工作,如“Java”這個(gè)Tag在我的博客、我所在的圈子、網(wǎng)站等各級(jí)的統(tǒng)計(jì),不知道Lucence是否支持?
3.JavaEye使用了Tag技術(shù),不知道如何實(shí)現(xiàn)的?
————————————————————————————————————————————
這要看如何設(shè)計(jì)以及如何檢索,如果是搜索某個(gè)tag對(duì)應(yīng)的記錄,其實(shí)是非常快的,tag關(guān)聯(lián)表用復(fù)合主鍵,把tag_id作復(fù)合主鍵的第1個(gè),檢索是非常快的,因?yàn)橛昧酥麈I索引。
2.使用Lucene是一個(gè)非常好的建議,但是我希望對(duì)Tag的使用上做不少細(xì)化的工作,如“Java”這個(gè)Tag在我的博客、我所在的圈子、網(wǎng)站等各級(jí)的統(tǒng)計(jì),不知道Lucence是否支持?
如果是統(tǒng)計(jì)這個(gè),用數(shù)據(jù)庫(kù)效率也可以很高,加上適當(dāng)?shù)木彺妫ū热鐭衢Ttag緩存起來(lái))。lucence不清楚。
我當(dāng)時(shí)有點(diǎn)興趣的是如何查詢“購(gòu)買了某書的人也購(gòu)買了XX書”,這和標(biāo)簽關(guān)聯(lián)有點(diǎn)相似,可以做一些關(guān)聯(lián)性內(nèi)容的推送。以前在CSDN問了一個(gè),有人回復(fù)我一個(gè),可以查詢“購(gòu)買了C++編程語(yǔ)言書的人也購(gòu)買了XX書”,列出前2本:
- CREATE?TABLE?store?( ??
- ?bookname?VARCHAR(255)?NOT?NULL, ??
- ?username?VARCHAR(255)?NOT?NULL, ??
- ?PRIMARY?KEY?(bookname,?username) ??
- ); ??
- ??
- INSERT?INTO?store?(bookname,?username)?VALUES?('C++編程語(yǔ)言',?'a'); ??
- INSERT?INTO?store?(bookname,?username)?VALUES?('C++對(duì)象模型',?'a'); ??
- INSERT?INTO?store?(bookname,?username)?VALUES?('C++24小時(shí)通',?'a'); ??
- INSERT?INTO?store?(bookname,?username)?VALUES?('C++速成',?'a'); ??
- ??
- INSERT?INTO?store?(bookname,?username)?VALUES?('C++編程語(yǔ)言',?'b'); ??
- INSERT?INTO?store?(bookname,?username)?VALUES?('C++對(duì)象模型',?'b'); ??
- INSERT?INTO?store?(bookname,?username)?VALUES?('C++24小時(shí)通',?'b'); ??
- INSERT?INTO?store?(bookname,?username)?VALUES?('C++速成',?'b'); ??
- ??
- INSERT?INTO?store?(bookname,?username)?VALUES?('C++編程語(yǔ)言',?'c'); ??
- INSERT?INTO?store?(bookname,?username)?VALUES?('C++對(duì)象模型',?'c'); ??
- INSERT?INTO?store?(bookname,?username)?VALUES?('C++24小時(shí)通',?'c'); ??
- INSERT?INTO?store?(bookname,?username)?VALUES?('C++速成',?'c'); ??
- ??
- INSERT?INTO?store?(bookname,?username)?VALUES?('C++編程語(yǔ)言',?'d'); ??
- INSERT?INTO?store?(bookname,?username)?VALUES?('C++24小時(shí)通',?'d'); ??
- INSERT?INTO?store?(bookname,?username)?VALUES?('C++速成',?'d'); ??
- ??
- INSERT?INTO?store?(bookname,?username)?VALUES?('C++編程語(yǔ)言',?'e'); ??
- INSERT?INTO?store?(bookname,?username)?VALUES?('C++速成',?'e'); ??
- ??
- ? ??
- ??
- select?bookname,?count(*)?from?store?where?username?in ??
- ( ??
- ?select?username?from?store?where?bookname?=?'C++編程語(yǔ)言' ??
- ) ??
- and?bookname?<>?'C++編程語(yǔ)言' ??
- group?by?bookname ??
- having?count(*)?>=?0??
- order?by?count(*)?desc ??
- limit?2; ??
效率不太高。我覺得tag最應(yīng)該有的作用就是這個(gè)了。
————————————————————————————————————————————
一張tag表存儲(chǔ)tag到文章的對(duì)應(yīng)關(guān)系。
然后每個(gè)文章還有個(gè)tagtxt字段,各個(gè)tag用空格進(jìn)行分隔。
在增加/修改文章的時(shí)候,對(duì)tag進(jìn)行一次關(guān)聯(lián),并增加新增的tag。
現(xiàn)在有些問題。tag名字的修改,得修改所有的tagtxt字段。不過修改tag名字的功能應(yīng)當(dāng)不是很必要。