公司的電商平臺要作個站內信。主要功能是給供貨商、經銷商、分銷員這些身份的人發送消息。好比供貨商修改了商品的價格、上架了商品等操做。須要通知到經銷商。經銷商能夠在本身的站內信裏搜尋到消息。html
照例都是先去網上找下成熟的站內信方案。大概找了幾種方案以下數據庫
如下是原文章 地址http://www.cnblogs.com/grenet/archive/2010/03/08/1680655.html服務器
1、網上站內信技術方案數據庫設計
站內信」不一樣於電子郵件,電子郵件經過專門的郵件服務器發送、保存。而「站內信」是系統內的消息,說白了,「站內信」的實現,就是經過數據庫插入記錄來實現的。函數
「站內信」有兩個基本功能。一:點到點的消息傳送。用戶給用戶發送站內信;管理員給用戶發送站內信。二:點到面的消息傳送。管理員給用戶(指定知足某一 條件的用戶羣)羣發消息。點到點的消息傳送很容易實現,本文再也不詳述。下面將根據不一樣的狀況,來講說「站內信」的羣發是如何實現的。優化
第一種狀況,站內的用戶是少許級別的。(幾十到上百)網站
這種狀況,因爲用戶的數量很是少,所以,沒有必要過多的考慮數據庫的優化,採用簡單的表格,對系統的設計也來的簡單,後期也比較容易維護,是典型的用空間換時間的作法。spa
數據庫的設計以下:表名:Message設計
ID:編號;SendID:發送者編號;RecID:接受者編號(如爲0,則接受者爲全部人);Message:站內信內容;Statue:站內信的查看狀態;PDate:站內信發送時間;orm
若是,某一個管理員要給全部人發站內信,則先遍歷用戶表,再按照用戶表中的全部用戶依次將站內信插入到Message表中。這樣,若是有56個用戶,則羣發一條站內信要執行56個插入操做。這個理解上比較簡單,比較耗損空間。
某一個用戶登錄後,查看站內信的語句則爲:
Select * FROM Message Where RecID=‘ID' OR RecID=0
第二種狀況,站內的用戶中量級別的(上千到上萬)。
若是仍是按照第一種狀況的思路。那發一條站內信的後果基本上就是後臺崩潰了。由於,發一條站內信,得重複上千個插入記錄,這還不是最主要的,關鍵是上千 乃至上萬條記錄,Message字段的內容是同樣的,而Message有大量的佔用存儲空間。比方說,Message字段有100個漢字,佔用200個字 節,那麼5萬條,就佔用200×50000=10000000個字節=10M。簡單的一份站內信,就佔用10M,這還讓不讓人活了。
所以,將原先的表格拆分爲兩個表,將Message的主體放在一個表內,節省空間的佔用
數據庫的設計以下:
表名:Message
ID:編號;SendID:發送者編號;RecID:接受者編號(如爲0,則接受者爲全部人);MessageID:站內信編號;Statue:站內信的查看狀態;
表名:MessageText
ID:編號;Message:站內信的內容;PDate:站內信發送時間;
在管理員發一封站內信的時候,執行兩步操做。先在MessageText表中,插入站內信的內容。而後在Message表中給全部的用戶插入一條記錄,標識有一封站內信。
這樣的設計,將重複的站內信的主體信息(站內信的內容,發送時間)放在一個表內,大量的節省存儲空間。不過,在查詢的時候,要比第一種狀況來的複雜。
第三種狀況,站內的用戶是大量級的(上百萬),而且活躍的用戶只佔其中的一部分。
你們都有這樣的經歷,某日看一個網站比較好,一時心情澎湃,就註冊了一個用戶。過了一段時間,因爲種種緣由,就忘記了註冊時的用戶名和密碼,也就再也不登錄了。那麼這個用戶就稱爲不活躍的。從實際來看,不活躍的用戶佔着不小的比例。
咱們以註冊用戶2百萬,其中活躍用戶只佔其中的10%。
就算是按照第二種的狀況,發一封「站內信」,那得執行2百萬個插入操做。可是其中的有效操做只有10%,由於另外的90%的用戶可能永遠都不會再登錄了。
在這種狀況下,咱們還得把思路換換。
數據庫的設計和第二種狀況同樣:
表名:Message
ID:編號;SendID:發送者編號;RecID:接受者編號(如爲0,則接受者爲全部人);MessageID:站內信編號;Statue:站內信的查看狀態;
表名:MessageText
ID:編號;Message:站內信的內容;PDate:站內信發送時間;
管理員發站內信的時候,只在MessageText插入站內信的主體內容。Message裏不插入記錄。
那麼,用戶在登陸之後,首先查詢MessageText中的那些沒有在Message中有記錄的記錄,表示是未讀的站內信。在查閱站內信的內容時,再將相關的記錄插入到Message中。
這個方法和第二種的比較起來。若是,活躍用戶是100%。二者效率是同樣的。而活躍用戶的比例越低,越能體現第三種的優越來。只插入有效的記錄,那些不活躍的,就再也不佔用空間了。
以上,是我對羣發「站內信」的實現的想法。
2、商品基本模型 已經需求
以上是搜索到的站內信大概的設計方案。原本我的打算採用第二種方案。後來被PK掉了。先大概說下咱們的商品模型和站內信的需求
供貨商有一件商品叫作電水壺。 三個經銷商分別上架供貨商的商品。並從新命名商品的標題。分別叫作電水壺A、電水壺B、電水壺C. 並都在售賣 這件商品。
這個時候供貨商下架了商品。 因爲經銷商是從供貨商那邊發貨。經銷商自己沒有存貨。貨物都在供貨。
那裏。全部供貨商下架了商品。須要系統強制下級經銷商的這些商品。 這時候就須要站內信發送消息給這些經銷商。告訴它商品下架了。
可是這裏有個問題。 對供貨商來講。 供貨商站內信的收件箱看到的信息應該是 「電水壺下架」。可是經銷商A、B、C三我的看到的消息內容分別是 「電水壺A下架」 「電水壺B下架」 「電水壺C下架」。 即消息內容不是徹底同樣的。經銷商看到的消息內容是 經銷商商品標題。
因爲這個需求最終沒有采用搜到的方案 緣由以下。
一、不但要作收件箱還要作發件箱。 雖然是同一個操做動做引發的 消息。可是發件箱和收件箱的消息內容不同。並且收件箱每一個人收到的消息也不一樣。 若是用方案二和方案3、。只保留一份消息內容的話。不符合需求
二、咱們的站內信 只是正對賣家的 不是針對買家的。全部人羣達到千萬級別。全部能夠用簡單點的方式。方便處理和維護、
三、站內信不是郵箱。不須要一直保留全部數據。 只須要保留一段時間的數據
3、設計方案
流程
數據庫設計
說下這樣設計的緣由以及要點。
一、這個是站內信不是郵箱不用 一直保留數據。 全部防止數據的日益增大 會有個定時crontab腳本去刪除超過100天的消息記錄。 這裏的100天看產品的需求
二、這裏雖然消息是系統發送的。可是觸發人士供貨商。 全部供貨商的發件箱 內容跟 經銷商的收件箱內容不一致。 全部 發件箱和收件箱 都要保留消息內容。
3,發件箱至關於簡單的落地一份數據。由於調用方須要調用 站內信服務落地消息。全部落地消息的時候。沒有邏輯。就是一份數據。 這樣能迅速完成調用方自己的操做。而不會阻塞在。不數據寫入發件箱的過程當中。
四、發件箱一有新消息立馬。拋出消息。通知腳本。來處理。這裏用腳原本處理 而不是調用接口的方式。緣由是。 首先每一個接收方 須要接受的消息內容都須要從新聚合其餘信息。 消息模板會有改動。 使用腳本修改起來方便; 其次發送的人羣 比較多時候。這個發送會比較耗時。 咱們通常會在在系統裏循環調用本身。 而是由外部觸發。 咱們的系統是以API調用的方式。 每一個API都有超時時間。 若是放到一個函數裏循環發送消息到收件箱。 超市系統會自動結束函數。
5. 消息落地後 。收件箱查消息 很是的方便。
總結:
1)設計方案的時候。 必定要根據本身的應用場景來。
2)想問題要清晰和深入。站內信不是郵箱。 有本身的特色。