MongoDB的应用:动态消息的设计实现
2010-11-26 17:19
651 查看
现在社交网站异常火爆,Facebook、人人、开心网在短短的几年内,引领了互联网的又一个时代—网络社交,如果说,第一个时代是通过门户网站提供的内
容,第二个时代是通过搜索引擎来主动获取内容,那么作为第三个时代的SNS,又是通过什么来进行的信息的传播呢?当然是利用的人与人之间的关系形成的网,
进行人与人之间的传播,而实现这种病毒式传播的工具就是信息的动态推送。
在OECP社区的策划设计时,我们不仅仅要做高质量的内容站点,另外很重要的部分就是要把这些高质量的内容主动的推送给用户,而要达到这种目标的手段就是
要有动态信息的推送功能。在一般的SNS系统中,朋友是维系人与人之间关系的纽带,而OECP社区中,维系人与人之间的纽带是什么,是共同关注的内容。所
以我们设计了关注功能来加强人与人之间关系和内容的直接推送。
OECP社区是一个以业务组件为主题的社区,所以OECP社区的关注对象除了用户外,还要有业务组件。下图为关注的关系图。
建立好关注的关系以后,我们就要根据用户建立的这些关系为用户推送相关动态。
如何设计消息动态功能呢?我们先来分析几个问题:
社区的动作比较频繁,产生的动态数据是实时存储,还是缓存后延迟存储,对效率有什么影响。
每个人产生的动态消息要在被关注的人之间分发,数据的膨胀速度非常快,如何解决大数据量的存储问题?
数据量非常庞大的时候,如何能提高我们读取的效率,普通的做法是采用缓存功能,是不是有其他的方法,能够保证程序即方便开发,又高效呢?
参考: SNS
中好友动态功能的设计思路
综合考虑以上因素,我们放弃了利用关系数据库的方案,而采用现在比较流行的MongoDB来存储。主要原因:
采用缓存机制进行存储和读取处理,增加开发的难度。
MongoDB是一个解决海量存储的文档型数据库,无模式的结构可以让存储的数据结构更加灵活。在普通的关系数据库中,不同类型的消息的内容要存在一个字
段中,一般采用JSON的格式存储,然后根据不同类型在解析显示出来。而MongoDB的无模式结构,就可以自由的定义各种字段,一个表中都可以存储不同
字段定义的数据,前台可以直接引用,非常方便。
在大数据量下的查询中,MongoDB的查询性能还是非常好的,所以MongoDB都可以作为基础缓存层。更为重要的是,MongoDB的写性能要远远强过非关系数据库。通过这个特性,我们就无需在设立缓存层,而直接实时的插入和查询,方便的开发。
MongoDB有一个ORM的实现,项目地址:http://code.google.com/p/morphia/
但是鉴于存储的同一个表中的数据结构不一致,我们就是要利用MongoDB的无模式的存储方式,故放弃了这种POJO的实现。接下来我们要开始设计MongDB的存储结构了。下面是UML类图:
首先要定义一个存储动态的结构:Dynamic
Channel-->动态所在的频道,比如博客、业务组件等,参见枚举类DynamicChannel
Type-->动态的类型,比如博客、关注、留言等,参见枚举类DynamicType
UserId-->产生该动态消息的用户编号
TargetId-->动态事件所关联的实体编号,比如发表了一篇博客,该处为博客ID
CreateTime-->动态产生的时间
BcIdà业务组件编号,如果该动态和业务组件有关系,则记录该业务组件的编号,以方便根据此显示业务组件的最新动态。
Data-->动态消息的内容。如果用关系型数据库存储的话,一般存储JSON结构的数据。该处我们直接定义了一个结构类,参见DynamicData
动态消息的结构设计完成以后,我们需要把这些消息推送到不同用户那里,所以必须定义一个用户动态类UserDynamic
Uid-->用户名
DynamicId-->Dynamic的ID
Channel-->动态所在的频道,比如博客、业务组件等,参见枚举类DynamicChannel
CreateTime-->动态产生的时间
BcId-->组件ID
为了能够在用户的个人空间里按照频道来查询用户的动态,我们需要存储Channel,为了能够方便检索用户关注的哪个组件的动态,我们存储了BcId。如
果我们还要更加细分到检索我关注的某个用户的动态,我们还需要在UserDynamic增加EventUserId。也许我们要问,为什么要加这么多的冗
余,因为这些字段在Dynamic都已经存在了。这就是因为MongoDB不是关系型的数据库,无法通过类似于关系数据库的关联查询进行读取,表和表之间
也是独立的,其实它没有表的概念,它的定义是Collection,所以我们必须在一个Collection中定义好我们需要的字段属性。
接下来我们就要设计功能的实现方式和解决方案。
采用事件机制(观察者模式),为各种业务操作定义不同的事件。该部分的设计思路OECP社区的其他同事随后会更大家分享。
编写动态监听器,对我关注的一些事件进行监听,并将监听到的内容传递给动态服务。
编写统一的动态处理服务,采用异步的方式,对动态进行实时的分发。
编写MongoDB统一的DAO
以后将陆续发布基于MongoDB的架构和设计实现的相关文章,敬请关注!
下面截取了几个图来展示动态在OECP社区中的效果:
全站动态:
用户的动态:
我的动态:
关注:
1、
/**
*动态所属的频道
*
*@author
yongtree
*@date
2010-8-13上午11:23:39
*@version
1.0
*/
public
enum
DynamicChannel {
@EnumDescription("博客")
Blog
, @EnumDescription("业务组件")
BC
, @EnumDescription("关注")
Attention
,
@EnumDescription("留言")
LeaveWord
,
@EnumDescription("其他")
Other
}
2、
/**
*动态类型<br>
*注释描述了相关的存储数据结构
*
*@author
yongtree
*@date
2010-8-12下午06:37:12
*@version
1.0
*/
public
enum
DynamicType {
@EnumDescription("发表博客")
Blog
, // {title:'博客标题',summary:'博客描述'}
@EnumDescription("回复博客")
PostBlog
, // {title:'博客标题',summary:'评论的内容','uid
','博主uid
'}
@EnumDescription("留言")
LeaveWord
, // {touid
:'yt
',touname
:'谭明智',summary:'留言内容'}
@EnumDescription("新开通业务组件")
NewBC
, // {bcname
:'组件的名称',bccode
:'bc1'}
@EnumDescription("创建组件主题")
BCSubject
, // {title:'主题的名称',subjectId:'subject',bccode
:'bc1',bcvc
:'1.0',bcname
:'财务总帐组件'}
@EnumDescription("发布组件WIKI")
BCWiki
, // {title:'文章标题',bccode
:'bc1',bcvc
:'1.0',bcname
:'财务总帐组件'}
@EnumDescription("挑错")
BCMistake
, // {title:'文章标题',summary:'评论的内容',bccode
:'bc1',bcvc
:'1.0',bcname
:'财务总帐组件'}
@EnumDescription("评论组件WIKI")
PostBCWiki
, // {title:'文章标题',summary:'评论的内容',bccode
:'bc1',bcvc
:'1.0',bcname
:'财务总帐组件',isSection:true[如果是true的话,则title是section的标题,否则为subject的标题],subjectId:'entity'}
@EnumDescription("发起组件讨论")
BCTopic
, // {title:'讨论的主题',bccode
:'bc1',bcname
:'财务总帐组件'}
@EnumDescription("回复组件讨论")
BCPost
, // {title:'讨论的主题',bccode
:'bc1',bcname
:'财务总帐组件'}
@EnumDescription("加入组件")
BCJoin
, // {bcname
:'财务总帐组件',bccode
:'bc1'}
@EnumDescription("关注用户")
AttendUser
, // {uid
:'yt
',username
:'谭明智'}
@EnumDescription("关注组件")
AttendBC
, // {bcname
:'财务总帐组件',bccode
:'bc1'}
@EnumDescription("加入本站")
Reg
// {}
}
相关文件请参考附件。
MongoService.java
MongoFSServiceImpl.java
MongoFSService.java
MongoFSServiceImpl.java
容,第二个时代是通过搜索引擎来主动获取内容,那么作为第三个时代的SNS,又是通过什么来进行的信息的传播呢?当然是利用的人与人之间的关系形成的网,
进行人与人之间的传播,而实现这种病毒式传播的工具就是信息的动态推送。
在OECP社区的策划设计时,我们不仅仅要做高质量的内容站点,另外很重要的部分就是要把这些高质量的内容主动的推送给用户,而要达到这种目标的手段就是
要有动态信息的推送功能。在一般的SNS系统中,朋友是维系人与人之间关系的纽带,而OECP社区中,维系人与人之间的纽带是什么,是共同关注的内容。所
以我们设计了关注功能来加强人与人之间关系和内容的直接推送。
OECP社区是一个以业务组件为主题的社区,所以OECP社区的关注对象除了用户外,还要有业务组件。下图为关注的关系图。
建立好关注的关系以后,我们就要根据用户建立的这些关系为用户推送相关动态。
如何设计消息动态功能呢?我们先来分析几个问题:
社区的动作比较频繁,产生的动态数据是实时存储,还是缓存后延迟存储,对效率有什么影响。
每个人产生的动态消息要在被关注的人之间分发,数据的膨胀速度非常快,如何解决大数据量的存储问题?
数据量非常庞大的时候,如何能提高我们读取的效率,普通的做法是采用缓存功能,是不是有其他的方法,能够保证程序即方便开发,又高效呢?
参考: SNS
中好友动态功能的设计思路
综合考虑以上因素,我们放弃了利用关系数据库的方案,而采用现在比较流行的MongoDB来存储。主要原因:
采用缓存机制进行存储和读取处理,增加开发的难度。
MongoDB是一个解决海量存储的文档型数据库,无模式的结构可以让存储的数据结构更加灵活。在普通的关系数据库中,不同类型的消息的内容要存在一个字
段中,一般采用JSON的格式存储,然后根据不同类型在解析显示出来。而MongoDB的无模式结构,就可以自由的定义各种字段,一个表中都可以存储不同
字段定义的数据,前台可以直接引用,非常方便。
在大数据量下的查询中,MongoDB的查询性能还是非常好的,所以MongoDB都可以作为基础缓存层。更为重要的是,MongoDB的写性能要远远强过非关系数据库。通过这个特性,我们就无需在设立缓存层,而直接实时的插入和查询,方便的开发。
MongoDB有一个ORM的实现,项目地址:http://code.google.com/p/morphia/
但是鉴于存储的同一个表中的数据结构不一致,我们就是要利用MongoDB的无模式的存储方式,故放弃了这种POJO的实现。接下来我们要开始设计MongDB的存储结构了。下面是UML类图:
首先要定义一个存储动态的结构:Dynamic
Channel-->动态所在的频道,比如博客、业务组件等,参见枚举类DynamicChannel
Type-->动态的类型,比如博客、关注、留言等,参见枚举类DynamicType
UserId-->产生该动态消息的用户编号
TargetId-->动态事件所关联的实体编号,比如发表了一篇博客,该处为博客ID
CreateTime-->动态产生的时间
BcIdà业务组件编号,如果该动态和业务组件有关系,则记录该业务组件的编号,以方便根据此显示业务组件的最新动态。
Data-->动态消息的内容。如果用关系型数据库存储的话,一般存储JSON结构的数据。该处我们直接定义了一个结构类,参见DynamicData
动态消息的结构设计完成以后,我们需要把这些消息推送到不同用户那里,所以必须定义一个用户动态类UserDynamic
Uid-->用户名
DynamicId-->Dynamic的ID
Channel-->动态所在的频道,比如博客、业务组件等,参见枚举类DynamicChannel
CreateTime-->动态产生的时间
BcId-->组件ID
为了能够在用户的个人空间里按照频道来查询用户的动态,我们需要存储Channel,为了能够方便检索用户关注的哪个组件的动态,我们存储了BcId。如
果我们还要更加细分到检索我关注的某个用户的动态,我们还需要在UserDynamic增加EventUserId。也许我们要问,为什么要加这么多的冗
余,因为这些字段在Dynamic都已经存在了。这就是因为MongoDB不是关系型的数据库,无法通过类似于关系数据库的关联查询进行读取,表和表之间
也是独立的,其实它没有表的概念,它的定义是Collection,所以我们必须在一个Collection中定义好我们需要的字段属性。
接下来我们就要设计功能的实现方式和解决方案。
采用事件机制(观察者模式),为各种业务操作定义不同的事件。该部分的设计思路OECP社区的其他同事随后会更大家分享。
编写动态监听器,对我关注的一些事件进行监听,并将监听到的内容传递给动态服务。
编写统一的动态处理服务,采用异步的方式,对动态进行实时的分发。
编写MongoDB统一的DAO
以后将陆续发布基于MongoDB的架构和设计实现的相关文章,敬请关注!
下面截取了几个图来展示动态在OECP社区中的效果:
全站动态:
用户的动态:
我的动态:
关注:
1、
/**
*动态所属的频道
*
*@author
yongtree
*@date
2010-8-13上午11:23:39
*@version
1.0
*/
public
enum
DynamicChannel {
@EnumDescription("博客")
Blog
, @EnumDescription("业务组件")
BC
, @EnumDescription("关注")
Attention
,
@EnumDescription("留言")
LeaveWord
,
@EnumDescription("其他")
Other
}
2、
/**
*动态类型<br>
*注释描述了相关的存储数据结构
*
*@author
yongtree
*@date
2010-8-12下午06:37:12
*@version
1.0
*/
public
enum
DynamicType {
@EnumDescription("发表博客")
Blog
, // {title:'博客标题',summary:'博客描述'}
@EnumDescription("回复博客")
PostBlog
, // {title:'博客标题',summary:'评论的内容','uid
','博主uid
'}
@EnumDescription("留言")
LeaveWord
, // {touid
:'yt
',touname
:'谭明智',summary:'留言内容'}
@EnumDescription("新开通业务组件")
NewBC
, // {bcname
:'组件的名称',bccode
:'bc1'}
@EnumDescription("创建组件主题")
BCSubject
, // {title:'主题的名称',subjectId:'subject',bccode
:'bc1',bcvc
:'1.0',bcname
:'财务总帐组件'}
@EnumDescription("发布组件WIKI")
BCWiki
, // {title:'文章标题',bccode
:'bc1',bcvc
:'1.0',bcname
:'财务总帐组件'}
@EnumDescription("挑错")
BCMistake
, // {title:'文章标题',summary:'评论的内容',bccode
:'bc1',bcvc
:'1.0',bcname
:'财务总帐组件'}
@EnumDescription("评论组件WIKI")
PostBCWiki
, // {title:'文章标题',summary:'评论的内容',bccode
:'bc1',bcvc
:'1.0',bcname
:'财务总帐组件',isSection:true[如果是true的话,则title是section的标题,否则为subject的标题],subjectId:'entity'}
@EnumDescription("发起组件讨论")
BCTopic
, // {title:'讨论的主题',bccode
:'bc1',bcname
:'财务总帐组件'}
@EnumDescription("回复组件讨论")
BCPost
, // {title:'讨论的主题',bccode
:'bc1',bcname
:'财务总帐组件'}
@EnumDescription("加入组件")
BCJoin
, // {bcname
:'财务总帐组件',bccode
:'bc1'}
@EnumDescription("关注用户")
AttendUser
, // {uid
:'yt
',username
:'谭明智'}
@EnumDescription("关注组件")
AttendBC
, // {bcname
:'财务总帐组件',bccode
:'bc1'}
@EnumDescription("加入本站")
Reg
// {}
}
相关文件请参考附件。
附件:
基于MongoDB的动态消息的设计实现.pdfMongoService.java
MongoFSServiceImpl.java
MongoFSService.java
MongoFSServiceImpl.java
相关文章推荐
- 应用框架的设计与实现——.NET平台(9 消息队列产品安装)
- 应用框架的设计与实现——.NET平台(9 消息队列服务代码分析)
- android应用开发-从设计到实现 3-9 Origami动态原型设计
- 设计模式的应用-动态代理实现事务控制
- android应用开发-从设计到实现 3-9 Origami动态原型设计
- JAVASCRIPT + PHP 应用二:网页设计中树形菜单的动态实现
- MongoDB practice:基于MongoDB的好友消息动态的实现思路(How to build activity-streaming with MongoDb)
- SilverLight企业应用框架设计【四】实体层设计+为客户端动态生成服务代理(自己实现RiaService)
- 动态分发,站内短信等web2.0应用的百万级消息机制简单实现
- JavaScript + PHP 应用二:网页设计中树形菜单的动态实现
- MongoDB之十大应用设计技巧
- hander同步技巧 利用post之后的消息是最后完成的,实现同步。关键看waitDone的实现。带面精简Camera应用。
- android应用开发-从设计到实现 4-6界面的整体布局
- [置顶] spring boot 使用activeMQ实现消息队列简单应用
- COM 组件设计与应用(八)——实现多接口
- 使用Biztalk Server实现基于消息的状态机设计模式
- android应用开发-从设计到实现 3-1 原型设计
- highcharts 高级应用—动态曲线的实现
- iOS的动态创建实例方法和实现消息转发
- 在SAE使用Apple Push Notification Service服务开发iOS应用, 实现消息推送