程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 數據庫知識 >> MYSQL數據庫 >> MySQL綜合教程 >> MySQL案例分享之系統消息

MySQL案例分享之系統消息

編輯:MySQL綜合教程

MySQL案例分享之系統消息


從前有個大師,率領一群徒弟,為客戶做了一個軟件系統。某天,客戶提出了一個新的需求,向系統中的所有用戶發送系統消息。由於當時系統剛上線不久,系統中的用戶也就幾十個。大師為了考驗自己的徒弟,便將該需求分配給他的徒弟,要求每個人都做一套方案出來,於是便有了下面的故事。

 

徒弟們接收到該項任務後,每個人都想到了先建一張系統消息表,每次發送系統消息時,將數據保存在詞表中,用戶就能從該表中讀取他個人的系統消息。用戶信息表的模型如下:

 

wKiom1SE7u-CszJkAAEpCtm5nzk125.jpg

 

基於上面的數據庫模型,徒弟們分別作了不同的實現方案,如下:

 

實現方案一:

 

小A是個急性子,領到任務後。立即開始了他的編程思路:將系統中的所有用戶都取出來,然後遍歷所有的用戶,每次迭代時插入一條系統消息。偽代碼如下:

List<FavUser> userList = favUserService.getAllUser();

for (FavUser favUser : userList){

SysMessage sysMessage = new SysMessage();

...

sysMessage.setReceiveUserId(favUser.getUserId());

sysMessageService.addSysMessage(sysMessage);

}

由於系統中的用戶較少,小A幾遍測試,發現系統中運行良好,便將該方案提交了上去。

 

實現方案二:


小B接到任務後,想到應該先把系統中所有的用戶Ids取出來,然後遍歷這些ids,每次迭代時都插入一條系統消息。基於此,小B的偽代碼如下:

List<Integer> userIdsList = favUserService.getAllUserIds();

for (Integer userId : userIdsList ){

SysMessage sysMessage = new SysMessage();

...

sysMessage.setReceiveUserId(userId);

sysMessageService.addSysMessage(sysMessage);

}

由於系統中的用戶較少,小B幾遍測試,發現系統中運行良好,也將該方案提交了上去。

 

實現方案三:

 

小C接到任務後,考慮到每次插入的系統消息,除了用戶id不同外,其余的數據項都相同,便想到了批量插入數據。由於MySQL數據庫支持批量插入數據,小C設計出了執行的SQL語句與偽代碼:

 

執行的SQL語句如下:

< insert id= "addBatchSysMessage" parameterType= "com.favccxx.favsoft.SysMessage" >

insert into sys_message (MESSAGE_TITLE, MESSAGE_CONTENT, MESSAGE_STATUS, RECEIVE_USER_ID, RECEIVE_TIME, CREATE_TIME

)

values

<foreach collection= "list" item= "item" index = "index" separator= "," >

( #{item.messageTitle,jdbcType= VARCHAR },#{item.messageContent,jdbcType= VARCHAR }, #{item.messageStatus,jdbcType= CHAR }, #{item.receiveUserId,jdbcType= INTEGER },#{item.receiveTime,jdbcType= TIMESTAMP }, #{item.createTime,jdbcType= TIMESTAMP }

)

</foreach>

</ insert >


  偽代碼如下:
 

List<FavUser> userList = favUserService.getAllUser();

List<SysMessage> dataList = new ArrayList<SysMessage>();

for (FavUser favUser : userList){

sysMessage.setReceiveUserId(favUser.getUserId());

dataList.add(sysMessage);

}

List<SysMessage> subList = dataList.subList( , );

sysMessageService.addBatchSysMessage(subList);

小C向系統中添加了幾千個模擬用戶,測試系統運行良好。但發現將系統中的用戶增加至幾萬時,發送系統消息速度明顯變慢。於是,小C采用了分組的方式進行插入,每10,000條插入一次,系統運行良好。

實現方案四

 

小D接到任務後,考慮的也是批量插入數據,但與小C不同的是,他想通過執行一次SQL完成批量插入數據。即先將待發送的消息存入數據庫中,然後通過MySQL查詢並同時將數據插入系統消息。小D的MySQL設計如下:

< insert id= "addAllSysMessage" parameterType= "com.favccxx.favsoft.SysMessage" >

insert into sys_message ( MESSAGE_TITLE,

MESSAGE_CONTENT, MESSAGE_STATUS, RECEIVE_USER_ID,

RECEIVE_TIME, CREATE_USER_ID, CREATE_TIME

)

select

a.MESSAGE_TITLE as MESSAGE_TITLE,

a.MESSAGE_CONTENT as MESSAGE_CONTENT,

as MESSAGE_STATUS,

b.user_id AS RECEIVE_USER_ID,

now() as RECEIVE_TIME,

now() as CREATE_TIME

from sys_message_send_info a,

(

select user_id FROM auth_user

) b

where sendInfoId=#{sendInfoId}

</ insert >

1
int insertCount = sysMessageService.addAllSysMessage(sendInfoId);

  小D向系統中插入了10萬個模擬用戶,經測試,系統運行良好。以下是向113508個用戶發送消息的花費時間。

 

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved