• 站内信DB设计实现


    两年前,万仓一黍在博客园发了两篇关于站内信的设计实现博文,《群发“站内信”的实现》、《群发“站内信”的实现(续)》,其中阐述了他关于站内信群发的设计思想,很具有借鉴意义。他在设计时考虑到用户量和存储空间的占用等问题。当然,在他的两篇博文中强调了站内信的设计要考虑具体情况,没有理想的设计方案,他的设计只是对于群发(点到面)的解决方案。 在此简述一下他的设计方案,详细的可以移步万仓一黍的博客。

    万仓一黍的设计方案:

    站内信分为“点到点”和“点到面”,“点到点”属于私信,用户之间传递的信息,一对一传递。“点到面”,属于系统消息或者公共信息,属于一对多发送。

    站内信的设计既要考虑到投递的准确性(也就是该收到的人能收到信息),也要考虑信息持久化存储空间占用问题,在他的第一篇博文中详细进行了介绍。

    我们在此仅把第三种情况拿出来说明,也就是用户量为百万级,活跃用户只占其中的一部分。

    数据库的设计:

    表名:Message

    ID:编号;SendID:发送者编号;RecID:接受者编号(如为0,则接受者为所有人);MessageID:站内信编号;Statue:站内信的查看状态;

    表名:MessageText

    ID:编号;Message:站内信的内容;PDate:站内信发送时间;

    将一封Message分为两部分,一是存储内容,另一个是存储用户的查看状态。也就解决了关于群发信息的存储空间占用问题,不需要为每个用户插入相关数据。

    另外考虑到百万级用户量,活跃用户只占其中的一部分,不可能在发送一封系统消息时,在Message表中为每一个用户插入一条状态(标记为未读),如果一百万用户,那么发送一条消息,就得往Message表中插入一百万条标记状态的数据,显然不具有可行性。所以万仓一黍提出换下思路:

    在用户登录时检索Message和MessgaeText,将MessgaeText的ID 和Messgae 的MessageID 相匹配, 这样就有两种情况:

    一、没有找到  RecID= 自己ID 并且MessageText中的消息ID不包含在Messgae的MessageID中

           将此部分消息取出来,显示为该用户未读,在用户点击阅读的时候,将消息阅读状态写入Messgae表,Status=已读。

    二、找到RecID=自己 并且 MessageText中的消息ID包含在Messgae的MessageID中,Status标记为已读

           将此部分消息提前出来,显示为用户已读,如果想“删除”(当然是逻辑上的删除,并非物理数据库删除),设置该Status=删除。

    对于上面的设计方案,设计系统消息群发全部用户,是很适合的。但是受众面越小(即“点到面”的面越小),就不太合适,所以我们需要在此设计方案上进行扩展。

    只对上面提到的用户百万级且活跃用户只占一部分这种情况探讨。还是采用将消息内容和阅读状态分开设计。

    我们将点到点和点到面综合到一起考虑,并且精细化这个“面”,不再是笼统的全部用户。“面”可以是具有某一角色的用户、某一用户组的用户甚至一些不具有任何公共特征的散列用户。

    设计思路

    概述如下:我们将消息分为私信(Private)、公共消息(Public)、系统消息(Global)(或者将公共消息和系统消息合并为公共消息也可以),视情况而定。

    1. 点到点:一对一发送,属于私信Private
    2. 点到个别:(接收面为百位用户)一对多(几百)发送,采用私信方式(Private)
    3. 点到局部:(接收面为具有某些公共特征如用户组、用户角色),属于公共消息(Public)
    4. 点到全部:一对全部发送,属于系统消息(Global)

    数据库设计

    表名:Message

    ID:编号;RecID:接收者编号;MessageID:站内信编号;Statue:站内信的查看状态

    表名:MessageText

    ID:编号;SendID:发送者编号;Message:站内信的内容;Type:信息类型;Group:用户组ID;  PostDate:站内信发送时间

    其中Status状态有未读、已读、删除

            Type类型有Private(私信)、Public(公共消息)、Global(系统消息)

    第一种 点到点

      点到点发送属于私信,比如A用户发送给B用户,首先在MessageText表中插入消息内容并且设置Type=Private,同时在Message表中插入一条记录设置RecID=B,Status=未读

      用户B查找RecID=B,并且Staus为未读,Type=Private,显示为私信未读,点击阅读后改变Status=已读

      用户B查找RecID=B,并且Staus为已读,Type=Private,显示为私信已读,删除设置Status=删除

    第二种 点到个别

      采用和私信相同的方式,在发送一条消息时在MessageText表中插入消息内容并且设置Type=Private,同时在Message表中插入多条记录设置RecID=各接收者ID,Status=未读

      每个接收采用和私信一样的方式读取处理。

    第三种 点到局部

       点到局部是一对某角色或某用户组发送,例如管理员向普通用户组发送,在MessageText表插入消息内容,且设置Type=Public 和Group为用户组ID

       用户登录后分两种情况:

      1、未找到RecId=自己ID 且 MessageText中(Type=Public 和Group=自己所在组 )  的消息ID不包含在Messgae的MessageID中

           提取出来显示为用户公共消息未读,在用户点击阅读的时候,将消息阅读状态写入Messgae表,Status=已读。

      2、找到RecId=自己ID 且 MessageText中(Type=Public 和Group=自己所在组 ) 的消息ID包含在Messgae的MessageID中

          将此部分消息提取出来,显示为用户公共消息已读,如果想“删除”(当然是逻辑上的删除,并非物理数据库删除),设置该Status=删除。

          注:此时可以不验证Group=自己所在组

    第四种 点到全部

        点到全部和点到局部采用类似的处理方式。例如管理员向普通用户组发送,在MessageText表插入消息内容,且设置Type=Global

        用户登录后分两种情况:

        1、未找到RecId=自己ID 且 MessageText中(Type=Global ) 的消息ID不包含在Messgae的MessageID中

            提取出来显示为用户系统消息未读,在用户点击阅读的时候,将消息阅读状态写入Messgae表,Status=已读。

        2、找到RecId=自己ID 且 MessageText中(Type=Global ) 的消息ID包含在Messgae的MessageID中

            将此部分消息提取出来,显示为用户系统消息已读,如果想“删除”(逻辑上的删除,并非物理数据库删除),设置该Status=删除。

    处理流程

    我们再来看下整个处理流程,用户登录后系统是怎样提取和显示信息的。

    用户登录后,采用Ajax异步加载、统计用户站内信

    • Messgae表中RecId=自己ID 且Status=未读,显示为私信未读
    • Messgae表中RecId=自己ID 且Status=已读 且 Type=Private,显示为私信已读
    • Messgae表中未找到RecId=自己ID 且 MessageText中(Type=Public 和Group=自己所在组 ) 的消息ID不包含在Messgae的MessageID中,显示为公共消息未读            
    • Messgae表中找到RecId=自己ID 且 MessageText中(Type=Public ) 的消息ID包含在Messgae的MessageID中 ,显示为公共消息已读
    • Messgae表中未找到RecId=自己ID 且 MessageText中(Type=Global ) 的消息ID不包含在Messgae的MessageID中 ,显示为系统消息未读
    • Messgae表中找到RecId=自己ID 且 MessageText中(Type=Global ) 的消息ID包含在Messgae的MessageID中 ,显示为系统消息已读

    原文地址:http://blog.csdn.net/yun_yg/article/details/19919421

  • 相关阅读:
    深度学习入门零基础笔记(一)一些相关链接
    华为云计算笔记(摘要略读,零基础)(九)(虚拟化特性介绍华为虚拟化产品特性)
    华为云计算笔记(摘要略读,零基础)(八)(虚拟化特性介绍-虚拟化特性)
    华为云计算笔记(摘要略读,零基础)(七)(虚拟化特性介绍集群特性介绍)
    华为云计算笔记(摘要略读,零基础)(六)(云计算存储基础介绍)
    华为云计算笔记(摘要略读,零基础)(五)(云计算网络基础介绍)
    华为云计算笔记(摘要略读,零基础)(四)(实验 FusionCompute安装)
    华为云计算笔记(摘要略读,零基础)(三)(KVM介绍、FusionCompute架构)
    华为云计算笔记(摘要略读,零基础)(一)(云计算介绍)
    基于kolla部署openstack
  • 原文地址:https://www.cnblogs.com/xiaommvik/p/6265886.html
Copyright © 2020-2023  润新知