當前位置:首頁 >  站長 >  網(wǎng)站運營 >  正文

大型網(wǎng)站架構系列之三 多對多關系的優(yōu)化設計

 2008-09-18 14:02  來源:   我來投稿 撤稿糾錯

  域名預訂/競價,好“米”不錯過

接上篇,大型網(wǎng)站架構系列之二 底層架構概論

上篇以用戶數(shù)據(jù)表為例介紹了基本的數(shù)據(jù)分割方案以及基本的配置方案。但是在2.0時代,這種簡單的列表索引已經(jīng)遠遠實現(xiàn)起來是問題的,多對多關 系將是最常見的關系?,F(xiàn)在我們針對web2.0數(shù)據(jù)中廣泛存在的多對多關系進行闡述和具體行為判斷,比如一個很簡單的例子,在2.0時代,好友功能是最常 被用到的,每個用戶會有很多的好友,同時也會是很多人的好友,那么這個數(shù)據(jù)量將會是用戶數(shù)的平方的級別。同樣,對于文章標簽,每個文章可以有多個標簽,而 每個標簽又可以有多個文章,這又是一個幾何乘積,數(shù)據(jù)量又會是個天文數(shù)字。

傳統(tǒng)的處理方案有兩種,一種是通過SEARCH的方法來實現(xiàn),一種是通過另建一個索引表,存貯對應的ID以進行存貯。對于第一種方案,因為要涉 及大量的LIKE查詢,性能不敢恭維,第二種的情況下,數(shù)據(jù)庫的行的數(shù)量也是驚人海量級別的,并且要跨表跨區(qū)查詢,還要維護數(shù)據(jù)的唯一性,數(shù)據(jù)處理過程相 當?shù)膹碗s性能也就不言而喻了。

文入正題,下面對數(shù)據(jù)多對多關系舉出來具體的解決方案,我們這里以標簽和文章之間的多對多關系為例來講解,大家可以舉一反三的思考群組和用戶之間,相冊和被圈用戶之間等等復雜的多對多關系。

首先濾清一下流程,我們以傳統(tǒng)方案的第二種為例,在傳統(tǒng)的數(shù)據(jù)庫設計中我們是如下走的:當一篇博文發(fā)布的時候并插入標簽的時候一般是三步走(也 可以理解為四步,以為還要判斷標簽是否存在的問題),第一步插入文章數(shù)據(jù)庫并獲取文章的ID,第二步插入標簽數(shù)據(jù)庫同時查詢標簽是否存在,如果存在就取出 標簽的ID,否則的話插入新標簽并取出ID,第三部,將文章的ID和標簽的ID插入索引表來建立關聯(lián)。如果這個時候在索引表上建立了索引的話就是災難性 的,特別是在數(shù)據(jù)量大的情況下,盡管它可以有效的提高查詢速度,但是發(fā)布的速度可能就會讓人無法忍受了。

我們處理的方法也是三部曲,對多對多關系進行進一步的處理。

用標簽的時候,我們用的最多的就是查詢標簽下的文章和顯示文章的標簽,所以我們實現(xiàn)這例就成了。

第一步,拋棄索引表。

對文章做冗余字段,加一個TAG列,我們可以講TAG的標簽如下寫[TagID,TagName]| [TagID,TagName]| [TagID,TagName] 同樣 對于TAG表,我們做如下冗余加個Article字段,如下內(nèi)容[ArticleID,Title]| [ArticleID, Title]| [ArticleID, Title],在需要增加的時候我們只要APPEND一下就可以了,至于ARTICLE的結(jié)構和TAG的結(jié)構可以參考我上一篇文章的介紹。其實根據(jù)需要還 可以存貯更多。

有人會問,為什么要存貯TagName和ArticleTitle呢,其實是為了避免跨表查詢和INNERJOIN查詢來做的,In查詢和跨表查詢會造成全表遍歷,所以我們在執(zhí)行的時候In查詢是必須要找到一個有效的替代方法的。

第二部:異步加載。

在設計模式下我們常思考的是單件模式,我們采用另類的單件模式來處理,也就是把文章和標簽之間的索引作為專門的進程來做,異步的實現(xiàn)。

為了避免文章在發(fā)布的時候以為要檢查TAG表而造成的線程擁堵,我們需要采取延遲加載的方案來做。服務器應該維護一個進程專業(yè)的對標簽和文章地段的查詢和索引,我們在發(fā)布文章的時候應該把標簽同步這一塊托管給另外的一個程序進行處理,并進行索引。

第三部:標簽緩存索引:

對于頻繁的判斷標簽去或者熱門的標簽我們還可以組織一套有效的索引,比如對于標簽“瘋狂代碼”和”傲博知識庫”,我們用樹來把它表示出來。對于 瘋狂代碼我們索引一個瘋,其實用程序表達就是瘋狂代碼[0],同樣傲博知識庫就是傲博知識庫[0]。而在數(shù)組”瘋”中存貯以瘋開頭的標簽組,以”傲”的數(shù) 組中存貯以”傲”開頭的標簽。如果量更大的話還可以再做二級索引。

這涉及另外一個話題了就是分詞,上面是一個簡單的分詞方案,大家在進行GOOGLE搜索的時候應該很輸入它的Suggest方法吧,就是這個道理。最終講標簽有效的索引,并提取熱門的作為一個全局靜態(tài)變量,我們就可以繞過數(shù)據(jù)查詢這一關,對第二部的單件模式又是一個進化。

以上是對多對多關系的一個簡單的架構說明,肯定有人會問,如果這樣做的話工作量不是太大了嗎,分詞處理什么的,對每個多對多關系進行處理。

OK,咱們可以進一步的把它來抽象化,我們用TableA 表示Article表,用TagbleT表示Tag表,我們可以講字段抽象化出來,也就是一個ID,一個Tag的String 同理對于標簽表也是如此。朋友們應該可以理解我的意思了。

對,就是做個代碼生成器把對應的多對多關系給生成出來,這個很好寫的,幾個Append就可以搞定。如果想更方便的處理,那么把這個東西做成單件的模式抽象化出來,然后再違反一下原則,做成基類,其他關系繼承這個基類。。。。。剩下的應該很簡單了,具體實現(xiàn)大家思考吧。

請參照第二篇的文章進行進一步優(yōu)化設計來實現(xiàn)更高的負載性能

下章接著講述數(shù)據(jù)分割和散列方面的內(nèi)容

瘋狂代碼原創(chuàng)發(fā)布,同步發(fā)布于 和

轉(zhuǎn)載請注明出處

申請創(chuàng)業(yè)報道,分享創(chuàng)業(yè)好點子。點擊此處,共同探討創(chuàng)業(yè)新機遇!

相關文章

熱門排行

信息推薦