上一篇寫了基於resin4.0+websocket實現私信功能服務端消息推送文章,趁熱打鐵,在寫一篇關於私信功能的數據庫設計文章,非代碼篇,但願想對第一次作設計並開發私信功能的同窗有點幫助。mysql
項目需求:私信功能,實現像對方發送私信消息後,在個人私信列表頁面顯示與發送或者接受消息的人列表,列表每條記錄只顯示與該對話的最新的一條消息。 點擊列表中的任意一條,進入到消息對話詳情頁面,按照倒序顯示該對話的詳細內容。同時在這兩個頁面均可以進行刪除對話,私信列表頁面刪除是與對方的全部會話,私信詳情頁面刪除的是某一條對話,並且單方刪除對話記錄,不影響對方查看。(有點繞。。。)web
軟件環境: mysqlsql
說了這麼多,其實總結起來就那麼幾個重要的點,一是私信列表每條記錄只顯示最後一條記錄,二是單方刪除對話記錄,不影響對方查看。先上數據表,而後在逐一解釋下。數據庫
CREATE TABLE `private_message` (
`id` bigint(20) NOT NULL auto_increment COMMENT '主鍵Id',
`user_id` bigint(20) NOT NULL COMMENT '發送者Id',
`friend_id` bigint(20) NOT NULL COMMENT '接受者Id',
`sender_id` bigint(20) NOT NULL COMMENT '發送者id',
`receiver_id` bigint(20) NOT NULL COMMENT '接受者Id',
`message_type` tinyint(4) NOT NULL COMMENT '消息類型,1:普通消息 2:系統消息',
`message_content` varchar(500) NOT NULL COMMENT '消息內容',
`send_time` datetime NOT NULL COMMENT '消息發送時間',
`status` tinyint(4) NOT NULL default '1' COMMENT '消息狀態 1:未讀 2:已讀 3:刪除',
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=7 DEFAULT CHARSET=utf8;websocket
創建private_message表,字段說明:
id:主鍵,自增加
user_id: 發送者id,非真實發送者id
friend_id: 接受者id,非真實接受者id
sender_id:發送者id,真實的發送者id
receiver_id:接受者id,真實的接受者id
message_type:消息類型,1:普通消息 2:系統消息,區分消息列表,能夠發送不一樣類型的消息內容
message_content:消息內容
send_time:消息發送時間
status:消息狀態 1:未讀 2:已讀 3:刪除,標記不一樣消息狀態,能夠實現統計未讀消息數,邏輯刪除用戶恢復等併發
看到這裏你們該鬱悶了,怎麼弄兩個發送者id,接受者id呢?socket
這裏由於考慮到單方刪除記錄,不影響對方查看的功能,因此這裏面咱們須要在發送私信時,插入兩份同樣content內容的數據,可是在user_id,friend_id上面作點手腳了,在兩次插入數據時,第二次插入的數據跟第一次插入的數據的user_id和friend_id對調。也就是:數據庫設計
INSERT INTO `private_message` VALUES ('1', '121', '127', '121', '127', '1', 'hello word', '2015-09-09 10:25:43', '2');
INSERT INTO `private_message` VALUES ('2', '127', '121', '121', '127', '1', 'hello word', '2015-09-09 10:26:41', '1');
INSERT INTO `private_message` VALUES ('3', '127', '121', '127', '121', '1', '你是程序猿嗎?', '2015-09-11 10:30:16', '2');
INSERT INTO `private_message` VALUES ('4', '121', '127', '127', '121', '1', '你是程序猿嗎?', '2015-09-11 10:30:59', '2');高併發
這麼一來,就能夠知足咱們的需求了。第一條和第四條記錄是給121用戶看,第二條和第三條記錄是給127看的,121刪除的時候刪除第一條或者第四條記錄,固然不會影響127看第二條和第三條記錄啦!!!網站
好了,如今能夠搞定其餘的功能需求了。
一、個人私信列表
SELECT p.id, COUNT(p.id) AS message_count,p.user_id,p.friend_id,p.sender_id,p.receiver_id,p.send_time,p.message_content, u.`name` AS receiver_name,u.img_url AS receiver_image FROM (SELECT * FROM private_message ORDER BY id DESC) p INNER JOIN user u on u.id=friend_id WHERE p.user_id=121 and p.`status` !=3 GROUP BY p.friend_id ORDER BY p.id DESC limit 0,10
二、個人私信列表詳情
SELECT p.id,p.message_content,p.sender_id,p.receiver_id,p.send_time,u.`name` AS sender_name,u.img_url AS sender_image,uu.`name` AS receiver_name FROM private_message p INNER JOIN user u on u.id=p.sender_id INNER JOIN user uu on uu.id=p.friend_id WHERE p.user_id=121 and p.friend_id=127 and p.`status` !=3 ORDER BY p.id DESC limit 0,10
三、個人私信列表頁面刪除整個會話
UPDATE private_message SETstatus=3 WHERE user_id=121 AND friend_id=127
四、個人私信列表詳情刪除單個對話
UPDATE private_message SET status=3 WHERE id=1
五、獲取用戶未讀消息數量
SELECT COUNT(*) FROM private_message WHERE user_id=121 AND receiver_id=127 AND status=1
固然,還能夠更新未讀消息爲已讀,將已刪除的用戶從回收站中恢復過來,發送系統消息等等均可以實現的啦。這是,確定有同窗會說了,這個表設計的數據冗餘,每條記錄插入兩遍,content內容多的話或者發送系統消息時,表數據太大,固然這個只是針對小型的私信功能,確定跟大型專一於社交類網站不同了,可是咱們也能夠將content內容拆分出去,新建一個content表,這裏關聯下id就能夠減小數據冗餘了。還有就是這個設計不涉及到高併發訪問啦!涉及到高併發這個那就得更復雜的設計和方法途徑解決啦!
最後,貼上項目私信功能截圖,做爲對上邊的設計的體現吧!
個人私信列表頁面:
個人私信列表詳情頁面: