站内信设计
一、網(wǎng)上站內(nèi)信技術(shù)方案
站內(nèi)信”不同于電子郵件,電子郵件通過(guò)專門(mén)的郵件服務(wù)器發(fā)送、保存。而“站內(nèi)信”是系統(tǒng)內(nèi)的消息,說(shuō)白了,“站內(nèi)信”的實(shí)現(xiàn),就是通過(guò)數(shù)據(jù)庫(kù)插入記錄來(lái)實(shí)現(xiàn)的。
“站內(nèi)信”有兩個(gè)基本功能。第一,點(diǎn)到點(diǎn)的消息傳送。用戶給用戶發(fā)送站內(nèi)信;管理員給用戶發(fā)送站內(nèi)信。第二,點(diǎn)到面的消息傳送。管理員給用戶(指定滿足某一 條件的用戶群)群發(fā)消息。點(diǎn)到點(diǎn)的消息傳送很容易實(shí)現(xiàn),本文不再詳述。下面將根據(jù)不同的情況,來(lái)說(shuō)說(shuō)“站內(nèi)信”的群發(fā)是如何實(shí)現(xiàn)的。
第一種情況,站內(nèi)的用戶是少量級(jí)別的。(幾十到上百)
這種情況,由于用戶的數(shù)量非常少,因此,沒(méi)有必要過(guò)多的考慮數(shù)據(jù)庫(kù)的優(yōu)化,采用簡(jiǎn)單的表格,對(duì)系統(tǒng)的設(shè)計(jì)也來(lái)的簡(jiǎn)單,后期也比較容易維護(hù),是典型的用空間換時(shí)間的做法。
數(shù)據(jù)庫(kù)的設(shè)計(jì)如下:表名:Message
ID:編號(hào);SendID:發(fā)送者編號(hào);RecID:接受者編號(hào)(如為0,則接受者為所有人);Message:站內(nèi)信內(nèi)容;Statue:站內(nèi)信的查看狀態(tài);PDate:站內(nèi)信發(fā)送時(shí)間;
如果,某一個(gè)管理員要給所有人發(fā)站內(nèi)信,則先遍歷用戶表,再按照用戶表中的所有用戶依次將站內(nèi)信插入到Message表中。這樣,如果有56個(gè)用戶,則群發(fā)一條站內(nèi)信要執(zhí)行56個(gè)插入操作。這個(gè)理解上比較簡(jiǎn)單,比較耗損空間。
某一個(gè)用戶登陸后,查看站內(nèi)信的語(yǔ)句則為:
Select * FROM Message Where RecID=‘ID’ OR RecID=0
第二種情況,站內(nèi)的用戶中量級(jí)別的(上千到上萬(wàn))。
如果還是按照第一種情況的思路。那發(fā)一條站內(nèi)信的后果基本上就是后臺(tái)崩潰了。因?yàn)?#xff0c;發(fā)一條站內(nèi)信,得重復(fù)上千個(gè)插入記錄,這還不是最主要的,關(guān)鍵是上千 乃至上萬(wàn)條記錄,Message字段的內(nèi)容是一樣的,而Message有大量的占用存儲(chǔ)空間。比方說(shuō),Message字段有100個(gè)漢字,占用200個(gè)字 節(jié),那么5萬(wàn)條,就占用200×50000=10000000個(gè)字節(jié)=10M。簡(jiǎn)單的一份站內(nèi)信,就占用10M,這還讓不讓人活了。
因此,將原先的表格拆分為兩個(gè)表,將Message的主體放在一個(gè)表內(nèi),節(jié)省空間的占用
數(shù)據(jù)庫(kù)的設(shè)計(jì)如下:
表名:Message
ID:編號(hào);SendID:發(fā)送者編號(hào);RecID:接受者編號(hào)(如為0,則接受者為所有人);MessageID:站內(nèi)信編號(hào);Statue:站內(nèi)信的查看狀態(tài);
表名:MessageText
ID:編號(hào);Message:站內(nèi)信的內(nèi)容;PDate:站內(nèi)信發(fā)送時(shí)間;
在管理員發(fā)一封站內(nèi)信的時(shí)候,執(zhí)行兩步操作。先在MessageText表中,插入站內(nèi)信的內(nèi)容。然后在Message表中給所有的用戶插入一條記錄,標(biāo)識(shí)有一封站內(nèi)信。
這樣的設(shè)計(jì),將重復(fù)的站內(nèi)信的主體信息(站內(nèi)信的內(nèi)容,發(fā)送時(shí)間)放在一個(gè)表內(nèi),大量的節(jié)省存儲(chǔ)空間。不過(guò),在查詢的時(shí)候,要比第一種情況來(lái)的復(fù)雜。
第三種情況,站內(nèi)的用戶是大量級(jí)的(上百萬(wàn)),并且活躍的用戶只占其中的一部分。
大家都有這樣的經(jīng)歷,某日看一個(gè)網(wǎng)站比較好,一時(shí)心情澎湃,就注冊(cè)了一個(gè)用戶。過(guò)了一段時(shí)間,由于種種原因,就忘記了注冊(cè)時(shí)的用戶名和密碼,也就不再登陸了。那么這個(gè)用戶就稱為不活躍的。從實(shí)際來(lái)看,不活躍的用戶占著不小的比例。
我們以注冊(cè)用戶2百萬(wàn),其中活躍用戶只占其中的10%。
就算是按照第二種的情況,發(fā)一封“站內(nèi)信”,那得執(zhí)行2百萬(wàn)個(gè)插入操作。但是其中的有效操作只有10%,因?yàn)榱硗獾?0%的用戶可能永遠(yuǎn)都不會(huì)再登陸了。
在這種情況下,我們還得把思路換換。
數(shù)據(jù)庫(kù)的設(shè)計(jì)和第二種情況一樣:
表名:Message
ID:編號(hào);SendID:發(fā)送者編號(hào);RecID:接受者編號(hào)(如為0,則接受者為所有人);MessageID:站內(nèi)信編號(hào);Statue:站內(nèi)信的查看狀態(tài);
表名:MessageText
ID:編號(hào);Message:站內(nèi)信的內(nèi)容;PDate:站內(nèi)信發(fā)送時(shí)間;
管理員發(fā)站內(nèi)信的時(shí)候,只在MessageText插入站內(nèi)信的主體內(nèi)容。Message里不插入記錄。
那么,用戶在登錄以后,首先查詢MessageText中的那些沒(méi)有在Message中有記錄的記錄,表示是未讀的站內(nèi)信。在查閱站內(nèi)信的內(nèi)容時(shí),再將相關(guān)的記錄插入到Message中。
這個(gè)方法和第二種的比較起來(lái)。如果,活躍用戶是100%。兩者效率是一樣的。而活躍用戶的比例越低,越能體現(xiàn)第三種的優(yōu)越來(lái)。只插入有效的記錄,那些不活躍的,就不再占用空間了。
以上,是我對(duì)群發(fā)“站內(nèi)信”的實(shí)現(xiàn)的想法。
二、商品基本模型 已經(jīng)需求
以上是搜索到的站內(nèi)信大概的設(shè)計(jì)方案。本來(lái)個(gè)人打算采用第二種方案。后來(lái)被PK掉了。先大概說(shuō)下我們的商品模型和站內(nèi)信的需求
供貨商有一件商品叫做電水壺。 三個(gè)經(jīng)銷商分別上架供貨商的商品。并重新命名商品的標(biāo)題。分別叫做電水壺A、電水壺B、電水壺C. 并都在售賣 這件商品。
這個(gè)時(shí)候供貨商下架了商品。 由于經(jīng)銷商是從供貨商那邊發(fā)貨。經(jīng)銷商本身沒(méi)有存貨。貨物都在供貨。
那里。所有供貨商下架了商品。需要系統(tǒng)強(qiáng)制下級(jí)經(jīng)銷商的這些商品。 這時(shí)候就需要站內(nèi)信發(fā)送消息給這些經(jīng)銷商。告訴它商品下架了。
但是這里有個(gè)問(wèn)題。 對(duì)供貨商來(lái)說(shuō)。 供貨商站內(nèi)信的收件箱看到的信息應(yīng)該是 “電水壺下架”。但是經(jīng)銷商A、B、C三個(gè)人看到的消息內(nèi)容分別是 “電水壺A下架” “電水壺B下架” “電水壺C下架”。 即消息內(nèi)容不是完全一樣的。經(jīng)銷商看到的消息內(nèi)容是 經(jīng)銷商商品標(biāo)題。
由于這個(gè)需求最終沒(méi)有采用搜到的方案 原因如下。
1、不但要做收件箱還要做發(fā)件箱。 雖然是同一個(gè)操作動(dòng)作引起的 消息。但是發(fā)件箱和收件箱的消息內(nèi)容不一樣。而且收件箱每個(gè)人收到的消息也不同。 如果用方案二和方案三、。只保留一份消息內(nèi)容的話。不符合需求
2、我們的站內(nèi)信 只是正對(duì)賣家的 不是針對(duì)買家的。所有人群達(dá)到千萬(wàn)級(jí)別。所有可以用簡(jiǎn)單點(diǎn)的方式。方便處理和維護(hù)、
3、站內(nèi)信不是郵箱。不需要一直保留所有數(shù)據(jù)。 只需要保留一段時(shí)間的數(shù)據(jù)
三、設(shè)計(jì)方案
流程:
數(shù)據(jù)庫(kù)設(shè)計(jì):
說(shuō)下這樣設(shè)計(jì)的原因以及要點(diǎn)。
1、這個(gè)是站內(nèi)信不是郵箱不用 一直保留數(shù)據(jù)。 所有防止數(shù)據(jù)的日益增大 會(huì)有個(gè)定時(shí)crontab腳本去刪除超過(guò)100天的消息記錄。 這里的100天看產(chǎn)品的需求
2、這里雖然消息是系統(tǒng)發(fā)送的。但是觸發(fā)人士供貨商。 所有供貨商的發(fā)件箱 內(nèi)容跟 經(jīng)銷商的收件箱內(nèi)容不一致。 所有 發(fā)件箱和收件箱 都要保留消息內(nèi)容。
3,發(fā)件箱相當(dāng)于簡(jiǎn)單的落地一份數(shù)據(jù)。因?yàn)檎{(diào)用方需要調(diào)用 站內(nèi)信服務(wù)落地消息。所有落地消息的時(shí)候。沒(méi)有邏輯。就是一份數(shù)據(jù)。 這樣能迅速完成調(diào)用方本身的操作。而不會(huì)阻塞在。不數(shù)據(jù)寫(xiě)入發(fā)件箱的過(guò)程中。
4、發(fā)件箱一有新消息立馬。拋出消息。通知腳本。來(lái)處理。這里用腳本來(lái)處理 而不是調(diào)用接口的方式。原因是。 首先每個(gè)接收方 需要接受的消息內(nèi)容都需要重新聚合其他信息。 消息模板會(huì)有改動(dòng)。 使用腳本修改起來(lái)方便; 其次發(fā)送的人群 比較多時(shí)候。這個(gè)發(fā)送會(huì)比較耗時(shí)。 我們一般會(huì)在在系統(tǒng)里循環(huán)調(diào)用自己。 而是由外部觸發(fā)。 我們的系統(tǒng)是以API調(diào)用的方式。 每個(gè)API都有超時(shí)時(shí)間。 如果放到一個(gè)函數(shù)里循環(huán)發(fā)送消息到收件箱。 超市系統(tǒng)會(huì)自動(dòng)結(jié)束函數(shù)。
5、消息落地后 。收件箱查消息 非常的方便。
總結(jié):
1)設(shè)計(jì)方案的時(shí)候。 一定要根據(jù)自己的應(yīng)用場(chǎng)景來(lái)。2)想問(wèn)題要清晰和深刻。站內(nèi)信不是郵箱。 有自己的特點(diǎn)。
<script type="text/javascript"> $(function () { $('pre.prettyprint code').each(function () { var lines = $(this).text().split('\n').length; var $numbering = $('<ul/>').addClass('pre-numbering').hide(); $(this).addClass('has-numbering').parent().append($numbering); for (i = 1; i <= lines; i++) { $numbering.append($('<li/>').text(i)); }; $numbering.fadeIn(1700); }); }); </script>
總結(jié)
- 上一篇: js数组的排序 sort详解
- 下一篇: tomcat外网映射工具