站內信DB設計實現

2022-08-19 16:09:11 字數 2977 閱讀 9828

兩年前,萬倉一黍在發了兩篇關於站內信的設計實現博文,《**「站內信」的實現》、《**「站內信」的實現(續)》,其中闡述了他關於站內信**的設計思想,很具有借鑑意義。他在設計時考慮到使用者量和儲存空間的占用等問題。當然,在他的兩篇博文中強調了站內信的設計要考慮具體情況,沒有理想的設計方案,他的設計只是對於**(點到面)的解決方案。 在此簡述一下他的設計方案,詳細的可以移步萬倉一黍的部落格。

萬倉一黍的設計方案:

站內信分為「點到點」和「點到面」,「點到點」屬於私信,使用者之間傳遞的資訊,一對一傳遞。「點到面」,屬於系統訊息或者公共資訊,屬於一對多傳送。

站內信的設計既要考慮到投遞的準確性(也就是該收到的人能收到資訊),也要考慮資訊持久化儲存空間占用問題,在他的第一篇博文中詳細進行了介紹。

我們在此僅把第三種情況拿出來說明,也就是使用者量為百萬級,活躍使用者只佔其中的一部分。

資料庫的設計:

表名:message

id:編號;sendid:傳送者編號;recid:接受者編號(如為0,則接受者為所有人);messageid:站內信編號;statue:站內信的檢視狀態;

表名:messagetext

id:編號;message:站內信的內容;pdate:站內信傳送時間;

將一封message分為兩部分,一是儲存內容,另乙個是儲存使用者的檢視狀態。也就解決了關於**資訊的儲存空間占用問題,不需要為每個使用者插入相關資料。

另外考慮到百萬級使用者量,活躍使用者只佔其中的一部分,不可能在傳送一封系統訊息時,在message表中為每乙個使用者插入一條狀態(標記為未讀),如果一百萬使用者,那麼傳送一條訊息,就得往message表中插入一百萬條標記狀態的資料,顯然不具有可行性。所以萬倉一黍提出換下思路:

在使用者登入時檢索message和messgaetext,將messgaetext的id 和messgae 的messageid 相匹配, 這樣就有兩種情況:

一、沒有找到  recid= 自己id 並且messagetext中的訊息id不包含在messgae的messageid中

二、找到recid=自己 並且 messagetext中的訊息id包含在messgae的messageid中,status標記為已讀

將此部分訊息提前出來,顯示為使用者已讀,如果想「刪除」(當然是邏輯上的刪除,並非物理資料庫刪除),設定該status=刪除。

對於上面的設計方案,設計系統訊息**全部使用者,是很適合的。但是受眾面越小(即「點到面」的面越小),就不太合適,所以我們需要在此設計方案上進行擴充套件。

只對上面提到的使用者百萬級且活躍使用者只佔一部分這種情況**。還是採用將訊息內容和閱讀狀態分開設計。

我們將點到點和點到面綜合到一起考慮,並且精細化這個「面」,不再是籠統的全部使用者。「面」可以是具有某一角色的使用者、某一使用者組的使用者甚至一些不具有任何公共特徵的雜湊使用者。

概述如下:我們將訊息分為私信(private)、公共訊息(public)、系統訊息(global)(或者將公共訊息和系統訊息合併為公共訊息也可以),視情況而定。

點到點:一對一傳送,屬於私信private

點到個別:(接收面為百位使用者)一對多(幾百)傳送,採用私信方式(private)

點到區域性:(接收面為具有某些公共特徵如使用者組、使用者角色),屬於公共訊息(public)

點到全部:一對全部傳送,屬於系統訊息(global)

表名:message

id:編號;recid:接收者編號;messageid:站內信編號;statue:站內信的檢視狀態

表名:messagetext

id:編號;sendid:傳送者編號;message:站內信的內容;type:資訊型別;group:使用者組id;  postdate:站內信傳送時間

其中status狀態有未讀、已讀、刪除

type型別有private(私信)、public(公共訊息)、global(系統訊息)

點到點傳送屬於私信,比如a使用者傳送給b使用者,首先在messagetext表中插入訊息內容並且設定type=private,同時在message表中插入一條記錄設定recid=b,status=未讀

使用者b查詢recid=b,並且staus為已讀,type=private,顯示為私信已讀,刪除設定status=刪除

採用和私信相同的方式,在傳送一條訊息時在messagetext表中插入訊息內容並且設定type=private,同時在message表中插入多條記錄設定recid=各接收者id,status=未讀

每個接收採用和私信一樣的方式讀取處理。

點到區域性是一對某角色或某使用者組傳送,例如管理員向普通使用者組傳送,在messagetext表插入訊息內容,且設定type=public 和group為使用者組id

使用者登入後分兩種情況:

1、未找到recid=自己id 且 messagetext中(type=public 和group=自己所在組 )  的訊息id不包含在messgae的messageid中

2、找到recid=自己id 且 messagetext中(type=public 和group=自己所在組 ) 的訊息id包含在messgae的messageid中

將此部分訊息提取出來,顯示為使用者公共訊息已讀,如果想「刪除」(當然是邏輯上的刪除,並非物理資料庫刪除),設定該status=刪除。

注:此時可以不驗證group=自己所在組

點到全部和點到區域性採用類似的處理方式。例如管理員向普通使用者組傳送,在messagetext表插入訊息內容,且設定type=global

使用者登入後分兩種情況:

1、未找到recid=自己id 且 messagetext中(type=global ) 的訊息id不包含在messgae的messageid中

2、找到recid=自己id 且 messagetext中(type=global ) 的訊息id包含在messgae的messageid中

將此部分訊息提取出來,顯示為使用者系統訊息已讀,如果想「刪除」(邏輯上的刪除,並非物理資料庫刪除),設定該status=刪除。

我們再來看下整個處理流程,使用者登入後系統是怎樣提取和顯示資訊的。

使用者登入後,採用ajax非同步載入、統計使用者站內信

站內信設計

站內信設計 1 message表 欄位名 型別 是否null id int 自增長 否 messageid int 否 sendid int 否 reclid int 否 readstatus int 否 sendstatus int 否 id 編號 messageid 訊息id sendid 傳送...

站內信設計

一 網上站內信技術方案 站內信 不同於電子郵件,電子郵件通過專門的郵件伺服器傳送 儲存。而 站內信 是系統內的訊息,說白了,站內信 的實現,就是通過資料庫插入記錄來實現的。站內信 有兩個基本功能。第一,點到點的訊息傳送。使用者給使用者傳送站內信 管理員給使用者傳送站內信。第二,點到面的訊息傳送。管理...

站內信設計

公司的電商平台要做個站內信。主要功能是給供貨商 經銷商 分銷員這些身份的人傳送訊息。比如供貨商修改了商品的 上架了商品等操作。需要通知到經銷商。經銷商可以在自己的站內信裡搜尋到訊息。照例都是先去網上找下成熟的站內信方案。大概找了幾種方案如下 以下是原文章 位址 一 網上站內信技術方案 站內信 不同於...