站內信的實現思路表的設計


“站內信”不同於電子郵件,電子郵件通過專門的郵件服務器發送、保存。而“站內信”是系統內的消息,說白了,“站內信”的實現,就是通過數據庫插入記錄來實現的。

   “站內信”有兩個基本功能。一:點到點的消息傳送。用戶給用戶發送站內信;管理員給用戶發送站內信。二:點到面的消息傳送。管理員給用戶(指定滿足某一 條件的用戶群)群發消息。點到點的消息傳送很容易實現,本文不再詳述。下面將根據不同的情況,來說說“站內信”的群發是如何實現的。

  第一種情況,站內的用戶是少量級別的。(幾十到上百)

  這種情況,由於用戶的數量非常少,因此,沒有必要過多的考慮數據庫的優化,采用簡單的表格,對系統的設計也來的簡單,后期也比較容易維護,是典型的用空間換時間的做法。

  數據庫的設計如下:表名:Message

  ID:編號;SendID:發送者編號;RecID:接受者編號(如為0,則接受者為所有人);Message:站內信內容;Statue:站內信的查看狀態;PDate:站內信發送時間;

  如果,某一個管理員要給所有人發站內信,則先遍歷用戶表,再按照用戶表中的所有用戶依次將站內信插入到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%。兩者效率是一樣的。而活躍用戶的比例越低,越能體現第三種的優越來。只插入有效的記錄,那些不活躍的,就不再占用空間了。

以上,是我對群發“站內信”的實現的想法。

出處:http://grenet.cnblogs.com/

 

百萬級用戶量的站內信設計

1. 方案描述

該方案用於系統站內信功能模塊在百萬級用戶量情況下的效率問題,只是后台管理員給前台用戶發送站內信,用戶與用戶之間的發送不在討論內。

2. 方案詳情

假設系統的用戶量達到了200W,活躍用戶為10W,系統后台管理員要給全體用戶發送一條感謝信,如果按照之前的存儲方式,消息隊列需要插入200W條數據,可是除了活躍的10W用戶,其他用戶都忘了自己有該網站的賬號,他都有可能不再登陸該網站了,數據庫保存的消息隊列無意義了。

現表結構如下:

消息表
編號    ID    NUMBER
標題    TITLE    VARCHAR2(50)    50
正文    CONTENTS    VARCHAR2(1000)
發送狀態    STATUS    NUMBER
發送日期    SEND_DATE    DATE
發送方式    SEND_TYPE    NUMBER
最新創建人    FCU    VARCHAR2(50)    50
更新人    LCU    VARCHAR2(50)    50
創建時間    FCD    DATE
最新更新時間    LCD    DATE
刪除標記    DELETE_TAG    CHAR(1)    1 

消息容器
編號    ID    NUMBER
站內信ID    MESSAGE_ID    NUMBER
收件人ID    MEMBER_ID    NUMBER
是否已讀    READ_STATUS    NUMBER

會員表

主鍵    id    NUMBER
會員編號    u_number    NUMBER
電子郵箱    u_email    VARCHAR2(200)    200
密碼    u_passwd    VARCHAR2(50)    50
企業認證    company_admit    NUMBER(1)    1
帳號禁用    帳號禁用    NUMBER(1)    1
創建人    FCU    NUMBER
最后更新人    LCU    NUMBER
首次創建時間    FCD    DATE
最后更新時間    LCD    DATE
刪除標記    DETELE_TAG    char(1)    1 
在盡量不改變表結構的前提下,改變一下程序寫數據庫的方式:
后台管理員發送一條站內信,接收對象為全體會員,系統往站內信表插入一條站內信,其中發送方式區分接收的對象(0為全體發送,1為只發送給注冊會員,2為只發送給企業會員,3為指定會員發送),這樣,發送給全體會員的一條站內信暫時只生成了一條數據。

前台會員登陸的時候,根據會員自身的會員類型(普通會員,企業會員)查詢站內信表中屬於自己的最新消息(根據自己所持消息的最新時間與消息表的發送時間做 比對),往消息容器中插入自身與所持消息的關聯數據,默認未未讀,在前台會員點擊某一條未讀站內信的時候,將容器中的對應站內信狀態改為已讀。

如果后台管理員只指定發送站內信給某幾個會員,則往站內信表插入一條站內信后,將這幾個會員與該站內信的關聯直接往消息容器中寫關聯,不需要前台會員取。
另:因為改變了發送接收方式,后台管理員只指定發送站內信給某幾個會員,但是站內信狀態未未發送,只是保存草稿,需要往站內信主表增加一個字段,保存指定會員的id串,用於關聯此草稿與指定會員的關聯,此處就要求發送給指定會員的數量不能太多,需要限制。
這樣,百萬級用戶量的系統,活躍度為10%的用戶登陸系統,只生成了10W的數據,用戶活躍度越低,此方案效率越明顯,如果是100%活躍度的話,此方案和現有方法無區別。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM