文档章节

站内信 设计

冬瓜1
 冬瓜1
发布于 2016/01/21 18:15
字数 2468
阅读 108
收藏 2

公司的电商平台要做个站内信。主要功能是给供货商、经销商、分销员这些身份的人发送消息。比如供货商修改了商品的价格、上架了商品等操作。需要通知到经销商。经销商可以在自己的站内信里搜寻到消息。

  照例都是先去网上找下成熟的站内信方案。大概找了几种方案如下

 

以下是原文章 地址http://www.cnblogs.com/grenet/archive/2010/03/08/1680655.html

一、网上站内信技术方案

        站内信”不同于电子邮件,电子邮件通过专门的邮件服务器发送、保存。而“站内信”是系统内的消息,说白了,“站内信”的实现,就是通过数据库插入记录来实现的。

   “站内信”有两个基本功能。一:点到点的消息传送。用户给用户发送站内信;管理员给用户发送站内信。二:点到面的消息传送。管理员给用户(指定满足某一 条件的用户群)群发消息。点到点的消息传送很容易实现,本文不再详述。下面将根据不同的情况,来说说“站内信”的群发是如何实现的。

 

第一种情况,站内的用户是少量级别的。(几十到上百)

  这种情况,由于用户的数量非常少,因此,没有必要过多的考虑数据库的优化,采用简单的表格,对系统的设计也来的简单,后期也比较容易维护,是典型的用空间换时间的做法。

  数据库的设计如下:表名:Message

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

  如果,某一个管理员要给所有人发站内信,则先遍历用户表,再按照用户表中的所有用户依次将站内信插入到Message表中。这样,如果有56个用户,则群发一条站内信要执行56个插入操作。这个理解上比较简单,比较耗损空间。

  某一个用户登陆后,查看站内信的语句则为:

  Select * FROM Message Where RecID=‘ID' OR RecID=0

第二种情况,站内的用户中量级别的(上千到上万)。

   如果还是按照第一种情况的思路。那发一条站内信的后果基本上就是后台崩溃了。因为,发一条站内信,得重复上千个插入记录,这还不是最主要的,关键是上千 乃至上万条记录,Message字段的内容是一样的,而Message有大量的占用存储空间。比方说,Message字段有100个汉字,占用200个字 节,那么5万条,就占用200×50000=10000000个字节=10M。简单的一份站内信,就占用10M,这还让不让人活了。

  因此,将原先的表格拆分为两个表,将Message的主体放在一个表内,节省空间的占用

  数据库的设计如下:

  表名:Message

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

  表名:MessageText 

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

  在管理员发一封站内信的时候,执行两步操作。先在MessageText表中,插入站内信的内容。然后在Message表中给所有的用户插入一条记录,标识有一封站内信。

  这样的设计,将重复的站内信的主体信息(站内信的内容,发送时间)放在一个表内,大量的节省存储空间。不过,在查询的时候,要比第一种情况来的复杂。

第三种情况,站内的用户是大量级的(上百万),并且活跃的用户只占其中的一部分。

  大家都有这样的经历,某日看一个网站比较好,一时心情澎湃,就注册了一个用户。过了一段时间,由于种种原因,就忘记了注册时的用户名和密码,也就不再登陆了。那么这个用户就称为不活跃的。从实际来看,不活跃的用户占着不小的比例。

  我们以注册用户2百万,其中活跃用户只占其中的10%。

  就算是按照第二种的情况,发一封“站内信”,那得执行2百万个插入操作。但是其中的有效操作只有10%,因为另外的90%的用户可能永远都不会再登陆了。

  在这种情况下,我们还得把思路换换。

  数据库的设计和第二种情况一样:

  表名:Message

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

  表名:MessageText 

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

  管理员发站内信的时候,只在MessageText插入站内信的主体内容。Message里不插入记录。

  那么,用户在登录以后,首先查询MessageText中的那些没有在Message中有记录的记录,表示是未读的站内信。在查阅站内信的内容时,再将相关的记录插入到Message中。

  这个方法和第二种的比较起来。如果,活跃用户是100%。两者效率是一样的。而活跃用户的比例越低,越能体现第三种的优越来。只插入有效的记录,那些不活跃的,就不再占用空间了。

  以上,是我对群发“站内信”的实现的想法。

 

二、商品基本模型 已经需求

        以上是搜索到的站内信大概的设计方案。本来个人打算采用第二种方案。后来被PK掉了。先大概说下我们的商品模型和站内信的需求

    

 

        供货商有一件商品叫做电水壶。   三个经销商分别上架供货商的商品。并重新命名商品的标题。分别叫做电水壶A、电水壶B、电水壶C. 并都在售卖 这件商品。

        这个时候供货商下架了商品。  由于经销商是从供货商那边发货。经销商本身没有存货。货物都在供货。

那里。所有供货商下架了商品。需要系统强制下级经销商的这些商品。  这时候就需要站内信发送消息给这些经销商。告诉它商品下架了。

        但是这里有个问题。  对供货商来说。 供货商站内信的收件箱看到的信息应该是 “电水壶下架”。但是经销商A、B、C三个人看到的消息内容分别是  “电水壶A下架” “电水壶B下架” “电水壶C下架”。 即消息内容不是完全一样的。经销商看到的消息内容是 经销商商品标题。

 

由于这个需求最终没有采用搜到的方案 原因如下。

1、不但要做收件箱还要做发件箱。  虽然是同一个操作动作引起的  消息。但是发件箱和收件箱的消息内容不一样。而且收件箱每个人收到的消息也不同。  如果用方案二和方案三、。只保留一份消息内容的话。不符合需求

2、我们的站内信 只是正对卖家的 不是针对买家的。所有人群达到千万级别。所有可以用简单点的方式。方便处理和维护、

3、站内信不是邮箱。不需要一直保留所有数据。 只需要保留一段时间的数据

 

三、设计方案

流程

 

数据库设计

 

说下这样设计的原因以及要点。

1、这个是站内信不是邮箱不用  一直保留数据。  所有防止数据的日益增大 会有个定时crontab脚本去删除超过100天的消息记录。  这里的100天看产品的需求

2、这里虽然消息是系统发送的。但是触发人士供货商。 所有供货商的发件箱 内容跟  经销商的收件箱内容不一致。  所有 发件箱和收件箱 都要保留消息内容。

3,发件箱相当于简单的落地一份数据。因为调用方需要调用 站内信服务落地消息。所有落地消息的时候。没有逻辑。就是一份数据。  这样能迅速完成调用方本身的操作。而不会阻塞在。不数据写入发件箱的过程中。

4、发件箱一有新消息立马。抛出消息。通知脚本。来处理。这里用脚本来处理  而不是调用接口的方式。原因是。  首先每个接收方  需要接受的消息内容都需要重新聚合其他信息。  消息模板会有改动。 使用脚本修改起来方便; 其次发送的人群 比较多时候。这个发送会比较耗时。  我们一般会在在系统里循环调用自己。 而是由外部触发。 我们的系统是以API调用的方式。  每个API都有超时时间。 如果放到一个函数里循环发送消息到收件箱。  超市系统会自动结束函数。

5. 消息落地后 。收件箱查消息 非常的方便。

 

 

总结:

    1)设计方案的时候。 一定要根据自己的应用场景来。

    2)想问题要清晰和深刻。站内信不是邮箱。 有自己的特点。


© 著作权归作者所有

共有 人打赏支持
冬瓜1
粉丝 11
博文 42
码字总数 16987
作品 0
东城
程序员
设计篇--站内信设计思路之己见(基于上百万用户)

大家都知道站内信,分为少量(10-999用户),中量(1000-99999用户),大量(100W用户)不同的站内信架构,消耗存储空间,和效率也是不同的。 本人基于最大的架构,来于大家共同讨论,站内信...

Yomut
2016/08/29
88
0
请问OSCHINA的站内私信是怎么设计的?

oschina的站内信,可以看到所有与之有过来往的2个人的聊天记录.这个功能不错,比较直观. 数据库设计和查询时怎么做的啊?

funny-guy
2012/06/06
724
4
极益发布站内信及站内一对一通知集成插件

极益发布了站内信及站内一对一通知集成的插件,插件用途: 站内信模块 站内信可以按照用户组进行发送,以用户组区分收件人 站内通知模块 站内通知是在代码运行时,非操作者主动发送一条指定单...

极益科技
2017/09/20
822
0
StartBBS v1.2.0 轻量微社区发布

StartBBS(烧饼开源微社区系统)是一个基于 PHP+MySQL MVC架构开发的新型微社区系统,她轻量小巧 简单易用,强大高效,又简称 "STB(烧饼)"。 前台 UI 采用当前流行的 Bootstrap 和 jQuery...

startbbs
2014/12/15
3K
8
Mysql极浅谈之第三方登录数据表设计

由于web2.0时代的到来,用户表的设计也要考虑到第三方所需参数的设计,在此之前阅读过几个博客,特此总结一下,并说明一下自己为何如此设计。 考虑到扩展性,有人设计出用户表只保存 用户信息...

Walker大熊
2016/09/06
0
0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

JS三元运算示例

1. topFlag=topFlag ==0?1:0; 等于 if(topFlag=00){ topFlag=1; }else if(topFlag == 1){ topFlag=0; } 2. 5>3?alert('5大'):alert('3大'); 即 if(5>3){alert('5大')}else{alert('3大')}; 注......

森火
今天
0
0
利用Slf4j的MDC跟踪方法调用链

why? 一个web项目通常提供很多URL访问地址, 项目一般都是分层处理,例如Controller——>Service——>DAO。 如果想根据日志查看用户一次请求都走了哪些方法(多数是查错误)。 如果系统是多人...

杨春炼
今天
9
0
Maven介绍及安装

Maven介绍及安装 以下内容是本人早期学习时的笔记,可能比较详实繁琐,现在复习一下Maven,顺便将内容抛出来,供大家一起学习进步。 一、Maven简介 Maven是Apache旗下的一款项目管理工具,是...

星汉
今天
0
0
小程序Aes解密

主要步骤: 1、下载AES源码(JS版) 2、在小程序中新建一个公共的文件夹,把AES源码拷贝进去(注意:需要暴露接口 module.exports = CryptoJS;) 3、添加一个用于加密解密的公共JS,可取名为...

Mr_Tea伯奕
今天
0
0
Go实现文件传输(基本传输可用)

发送端 package mainimport ("fmt""os""net""io")func SendFile(path string, connect net.Conn){file, oerr :=os.Open(path)if oerr !=nil{fmt.Println("Open", oerr)......

CHONGCHEN
今天
2
0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部