• 站内信系统的设计思路


    站内信是很多系统中的必备模块,结构设计也是老生常谈的问题。

    设计如下,其中mail表示用户-->用户之间的站内消息,notice表示系统-->用户之间的系统通知:

    两者结构基本一致,由于消息体本身可能包含text这种大容量的数据内容,因此将消息体独立存储在一个表中,再将消息体与收件方关联,是更加高效一些的做法。

    在多数应用场景中,可能会包含群发行为,例如:用户发送给好友的祝福;系统向部分用户发送通知。此时,遍历目标用户,批量插入至消息接收表,是比较可靠的做法。

    但是相对于mail站内信而言,notice有一个重要的需求是【广播】,即面向所有注册用户的群发消息。面对这种需求,当用户只有几十人时,这与前面的方法并无显著的差异。但是当用户体量过千,甚至过万的时候,这将是非常不智的做法。

    更好一些的做法,是将notice消息提设置为广播属性,当用户发生操作时,才将消息体导入接收信息表中。

    关于此类消息的查询,通常采用如下方式:

    select IFNULL(nr.id, 0) as id, IFNULL(nr.recipient_user_id, 0) as recipient_user_id, IFNULL(is_read, 0) as is_read, IFNULL(is_delete, 0) as is_delete
          , n.id as notice_id, notice_content, is_broadcast, n.create_time as notice_create_time
    from notice_receive nr
          right outer join notice n on nr.notice_id = n.id
    where (nr.recipient_user_id = #{uid} or is_broadcast = 1) and nc.create_time > #{user_create_time}

    查询当前用户的关联信息,以及所有广播信息,同时要注意,消息体时间大于用户注册时间,避免出现历史信息出现的状况。

    分析上面的sql语句,很明显right outer join是很消耗系统性能的查询操作,这并不是一个更优的方案,还需要进一步优化。

    再考虑一下用户日常操作消息的行为:未读消息设为已读、未读消息直接删除、已读消息删除(类似于Email系统的未读和已读之间的关系转换,并无同质考虑的意义)。

    上图是很常见的消息列表,结合前面的table结构,实际我们在做上面批量操作时,应有的查询是:

    where nr.id in (notice_receive id list)

    对于已经阅读过的消息,已经存在于notice_receive表中,可以直接根据notice_receive_id来操作。但是对于尚未阅读操作过的信息,则需要混合notice_id来进行操作,这样一来可能需要混合处理语句来完成。

    或许,在这种权衡选择当中,在用户登录、或者打开消息列表时,就将notice关联存入notice_receive表,或许会更好的解决这个问题。

  • 相关阅读:
    机器学习中的正则化问题(2)——理解正则化
    详解 Python 中的下划线命名规则
    编程面试的算法概念汇总
    group by多字段查询解决礼物统计
    一分钟学会Spring Boot多环境配置切换
    Maven 多模块父子工程 (含Spring Boot示例)
    第1章 Spring Cloud 构建微服务架构(一)服务注册与发现
    第3章 Spring Boot 入门指南
    第5章 Spring Boot 功能
    第4章 CentOS软件安装
  • 原文地址:https://www.cnblogs.com/bashenandi/p/6797796.html
Copyright © 2020-2023  润新知