设为首页 收藏本站
查看: 275|回复: 0

[经验分享] MySQL案例分享之系统消息

[复制链接]
累计签到:1 天
连续签到:1 天
发表于 2014-12-11 13:45:35 | 显示全部楼层 |阅读模式

从前有个大师,率领一群徒弟,为客户做了一个软件系统。某天,客户提出了一个新的需求,向系统中的所有用户发送系统消息。由于当时系统刚上线不久,系统中的用户也就几十个。大师为了考验自己的徒弟,便将该需求分配给他的徒弟,要求每个人都做一套方案出来,于是便有了下面的故事。


    徒弟们接收到该项任务后,每个人都想到了先建一张系统消息表,每次发送系统消息时,将数据保存在词表中,用户就能从该表中读取他个人的系统消息。用户信息表的模型如下:


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(0,1000);
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,
        0 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>

   
int insertCount = sysMessageService.addAllSysMessage(sendInfoId);


  小D向系统中插入了10万个模拟用户,经测试,系统运行良好。以下是向113508个用户发送消息的花费时间。


“可爱 的测试”发送给系统中【113508】个用户,共用时【2241】毫秒  
“fdgsdfg”发送给分组中【113508】个用户,共用时【2236】毫秒  
“平台所有用户系统消息”发送给系统中【113508】个用户,共用时【1916】毫秒   
“发生的飞洒的”发送给系统中【113508】个用户,共用时【1217】毫秒
“测试用户组33”发送给分组中【113508】个用户,共用时【1617】毫秒


运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.iyunv.com/thread-37829-1-1.html 上篇帖子: MySQL [ERROR] Table 'mysql.user' doesn't exist 下篇帖子: 在搭建mysql-mmm环境时报错
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表