先說一下需求和環境:
一個系統的站內信模塊,有存在大量的按部門群發的可能,相對的個人對個人的群發是比較少的。
數據庫是采用的mysql5.0。
最先的數據庫設計如下:
兩張表:
一張Msg表,字段如下:
id int 自增長id
senderid int 外鍵關聯發送者id
title varchar(128) 短信標題
content varchar(512) 短信內容
createTime datatime 發信時間
status tinyint 發件箱中的狀態:0--普通;1--刪除
一張user_has_msg表,字段如下:
id int
departmentid int 部門群發的時候外鍵關聯部門id,可以為空
receverid int 外鍵關聯收信人,可以為空
msgid int 外鍵關聯短信息
status tinyint 收件箱狀態:0--普通;1--刪除
readStatus tinyint 閱讀狀態:0--未讀;1--已讀
這樣設計是基於如下考慮的:
首先,msg表包含了發件箱所需要的所有信息,程序的時候寫發件箱的時候可以只考慮操作一張數據庫表。
第二,user_has_msg中,departmentid主要考慮的是存在大量的按照部門群發的可能,這樣的話,群發給一個部門的時候之需要在兩張表上個記錄一條數據,而不需要在user_has_msg中記錄該部門員工數條記錄。
但是,后來這個方案被我自己和同事討論后否決了,原因如下:
首先,departmentid的存在使得沒有用戶可以刪除收件箱中的站內信,因為刪除了,其他人的收件箱里也看不到。
第二,msg表不能保證顯示完所有的發件箱所需要的數據,因為只有着一張表的是后讀不出來收件人信息。
修改后的版本是:
將msg修改為只保純粹的信息的表:
id int 自增長id
title varchar(128) 短信標題
content varchar(512) 短信內容
createTime datatime 發信時間
將user_has_msg修改為保存各種關系和狀態的表:
id int
senderid int 外鍵關聯發送者id
receverid int 外鍵關聯收信人
msgid int 外鍵關聯短信息
sendStatus tinyint 發件箱中的狀態:0--普通;1--刪除
receveStatus tinyint 收件箱狀態:0--普通;1--刪除
readStatus tinyint 閱讀狀態:0--未讀;1--已讀
我記錄這個的想法一方面想記錄我自己的一些積累,另一方面是想像在網上找到更好的設計方法,尤其是解決群發這個問題。