论坛首页 Java企业应用论坛

请做架构的朋友一起讨论下SNS中好友动态功能建模的设计

浏览 66748 次
该帖已经被评为良好帖
作者 正文
   发表时间:2008-04-01  
timerri 写道
性能排序:
1.消息分发,最差,对于用户每个操作会产生大量io,不适合用户量多的情况。
2.用户操作日志使用单一表,较差,因为数据量多,每次查询后排序将会浪费大量时间。
3.对每个用户都建立一个操作日志表,较好,缺点是建立的表太多,但是查询速度相对快。
4.自行实现每个用户的操作日志表,直接使用链表,头指针使用定长顺序表或者hash表,查询的同时可以按时间合并链表,计算可控,速度最快。

2 性能还好,对user_id, operation_time做联合索引,问题不大,考虑到数据量大时带索引保存日志的性能影响,倒是可以用消息发到专门处理器,定时持久
0 请登录后投票
   发表时间:2008-04-01  
masterkey 写道
赫赫,这个话题有意思,我想应该是:

1.DBM(QDBM,NDBM,BDB等)存储用户的ID以及Memcached信息

key--->ID
value--->memcahcedID(location)

2.通过Memcached获取用户相关信息
相关信息包含:
     1.用户个人信息,状态
     2.好友信息
     3.行为状态

key--->id
value--->user(info,friend,action)


关于如何获取用户的相关信息,robbin已经提到了,通过用户的crud获取相关变化信息。


基于memcached的get/set是足够快的。对数据库压力方面的好处就不用提了。

至于使用什么语言,php,java,c,ruby,python等都可以,memcached都有相关语言的接口。



如果你的系统比较小或用户比较小。

第一步可以省略。

第二步memcached可以使用mysql或hsqldb进行替换。



考虑到有时间排序,不适合用memcache,除非memcache提供memcacheql支持排序
0 请登录后投票
   发表时间:2008-04-01  
很奇怪怎么会有这么多解决方案.

其实问题很简单的了,搞一个用户操作的日志表,每操作一步,就插入到这张表里面一些信息,定期清理一下就好了,顺便还可以做用户操作的简单监控了.
用jms这些方式太消耗资源了,人多了受不了
还是回到本源最简单.
0 请登录后投票
   发表时间:2008-04-01  
只要有Log表就可以了,如果业务上没有这样的表,就建一个动态表(专门为通知消息用的)就好了,每天清理一次过期数据,保留多少数据取决于系统对于“最近”和“最新”的定义,如果是48小时,那就是两天;
这样表数据量就不会很大,系统有多少用户,就可以算出有多少笔记录。水平切割也不会有任何问题。

查询上可以利用缓存等技术处理。性能问题应该不会太大。



0 请登录后投票
   发表时间:2008-04-03  
lllyq 写道
保证性能的基本就是尽量减少数据库操作,必要的冗余数据是不可避免的

就这个需求来说那就是只做一次多对多的user_firends关联多对一user_operation的查询就能获得所有的信息(更极端的把operation信息放到多对多表中,冗余太多一般不推荐),那就是一个sql搞定了,你打算用dataId来干什么,如果不是摆设就是动态获得操作信息了,相信你对sql对性能的影响有正确的概念,我就不多说了。

上面一次sql所需的参数就是user_id(用于关联), operation_time(用于排序), 操作信息operation_raw_data与操作相关,可以有不同的处理,简单就不举例了,复杂的举两个例子
发布了5张照片
username:香浓咖啡
picture_group_id:xxx
picture_number:5
picture_id:[1,2,3,4,5]
与某某加为好友
username:香浓咖啡
new_friends_id:[1,2,3,4,5]
new_friends_name:[企业邮箱,cobain,xxx,yyy,zzz]
这些信息拿到后怎么显示都可以,对应不同模板即可,实现方式可以用java, javascript,css等等,性能差别都不大


对于lllyq这两个例子.我有点疑问.首先你拿到的是ID,只有ID是不行的.如果你再拿ID去数据库去取数据显然会存在性能问题.再回过头来考虑到需求上的标题,摘要.图片.等等都是可点击的.所以应该即要有ID也要有ID对应的名称.这个operation_raw_data用来及接保存已经组织好结构的html源码就没有这些问题了.也举个例:
<div class="addFriends">
<span class="name"><a href="/id/1233" mce_href="/id/1233">香浓咖啡</a></span>
在 <span class="date"> 15 分钟前</span>加<span>
<a href="/id/1233" mce_href="/id/1233">香浓2</a><a href="/id/1233" mce_href="/id/1233">咖啡</a><a href="/id/1233" mce_href="/id/1233">香香</a>
</span>为好友
</di>


再类似的图片,结构也是这样.operation_raw_data及接用来保存这些片段不是更好么?
如果是我那个表设计的话.有几个对应的字段.保存的是一个JSON串.
如:DynamicName:[name:'香浓',id:'123456']
………………

 

0 请登录后投票
   发表时间:2008-04-04  
ithero 写道
lllyq 写道
保证性能的基本就是尽量减少数据库操作,必要的冗余数据是不可避免的

就这个需求来说那就是只做一次多对多的user_firends关联多对一user_operation的查询就能获得所有的信息(更极端的把operation信息放到多对多表中,冗余太多一般不推荐),那就是一个sql搞定了,你打算用dataId来干什么,如果不是摆设就是动态获得操作信息了,相信你对sql对性能的影响有正确的概念,我就不多说了。

上面一次sql所需的参数就是user_id(用于关联), operation_time(用于排序), 操作信息operation_raw_data与操作相关,可以有不同的处理,简单就不举例了,复杂的举两个例子
发布了5张照片
username:香浓咖啡
picture_group_id:xxx
picture_number:5
picture_id:[1,2,3,4,5]
与某某加为好友
username:香浓咖啡
new_friends_id:[1,2,3,4,5]
new_friends_name:[企业邮箱,cobain,xxx,yyy,zzz]
这些信息拿到后怎么显示都可以,对应不同模板即可,实现方式可以用java, javascript,css等等,性能差别都不大


对于lllyq这两个例子.我有点疑问.首先你拿到的是ID,只有ID是不行的.如果你再拿ID去数据库去取数据显然会存在性能问题.再回过头来考虑到需求上的标题,摘要.图片.等等都是可点击的.所以应该即要有ID也要有ID对应的名称.这个operation_raw_data用来及接保存已经组织好结构的html源码就没有这些问题了.也举个例:
<div class="addFriends">
<span class="name"><a href="/id/1233">香浓咖啡</a></span>
在 <span class="date"> 15 分钟前</span>加<span>
<a href="/id/1233">香浓2</a><a href="/id/1233">咖啡</a><a href="/id/1233">香香</a>
</span>为好友
</di>


再类似的图片,结构也是这样.operation_raw_data及接用来保存这些片段不是更好么?
如果是我那个表设计的话.有几个对应的字段.保存的是一个JSON串.
如:DynamicName:[name:'香浓',id:'123456']
………………

 

不太明白你说什么只有ID是不行的,我再解释一下,其实operation_raw_data是可以用json,对你的方案的建议就是没有必要还分多个字段,一个字段就搞定了,因为你这块的需求是不定的,预先定几个字段也是多余,不就是一个日志嘛,不影响到性能的情况下,String是万能的
1 请登录后投票
   发表时间:2008-04-07  
liujunsong 写道
很奇怪怎么会有这么多解决方案.

其实问题很简单的了,搞一个用户操作的日志表,每操作一步,就插入到这张表里面一些信息,定期清理一下就好了,顺便还可以做用户操作的简单监控了.
用jms这些方式太消耗资源了,人多了受不了
还是回到本源最简单.


简单的就是最好的。
0 请登录后投票
   发表时间:2008-04-08  
SNS....
要設計一個數據結構保存用戶于用戶之間的關系,就好比一長很大的圖。
不是隨便弄張表,日志就能搞定的
除了 CRUD還會啥..
0 请登录后投票
   发表时间:2008-04-12  

我此前参与的一个SNS项目,用的是方法3,升级若干次之后的表结构如下:
  `ic_id` bigint(20)  auto_increment,
  `user_id` int(11) ,
  `to_user_id` int(11) ,
  `change_date` datetime ,
  `change_class` int(11) ,
  `oid` bigint(20) ,
  `priv` int(11)  ,
  `extra_info` varchar(255) ,
  `extra_type` int(11) ,
  `status` tinyint(4)  ,
----------------------------------------------------------------------------------

朋友动态这种信息,根据网站的实际情况我觉得考虑如下几个问题:

1、是否只让用户看到最新n条?(海内的最新动态数量是固定的,采用先进先出原则,用户只能看到最新的n条;而UCH则可以每页150条允许用户翻页

2、用户增减好友后,朋友动态是否能够立刻体现出变化?(在海内,我如果在好友名单中删除一个人,好友动态还会有他的信息,只是不新增他的信息而已;而UCH里面,他的信息立刻消失。加一个人为朋友,也是一样的效果。

问题1和2有一定的联系,涉及到如何对朋友动态进行优化、缓存。

3、用户能否删除自己产生的动态?

4、阅读者是否可以删除其朋友动态中某一条动态?(在校内用户可以删除某一条朋友动态,在UCH用户可以屏蔽某人或者所有人的某类动态,在海内你只能看不能屏蔽

5、动态是否有阅读权限?

6、动态所指向的信息被修改、删除,动态是否要同步变化?(如果你修改了日志的标题,校内网的动态是不变的,而海内是变化的

ithero 写道

如果大家用过fackbook或者及国内的一些SNS对facebook拷贝的交友网站,就发现在在用户登录后首页有一个好友动态。它把好友最近发生的事情都罗列出来。
如用户个人首页对应有几种好友最近发生状态,blog,music,friend,video等等
实现方法个人考虑了几种(注意,前两种理论上可以实现,没具体去操作):
1),最简单那种,如果从不计较性能来考虑。实现这个功能就很简单。那就是对上面blog,music……等表都发起一条查询,再显示到页面。这种实现显示是不能让人接受的。
2),也笨拙,用sql union来实现,同样可以实现
3),这种实现就是针对好友动态创建一个表。即设计一个好友动态的对象。但怎么样来设计这个对象呢
如好友动态有如下属性:userId,friendUserId,createTime,余下的属性该如何来设计呢?是增加
blog,music,video等等通用名字的冗余字段(如name 对应blog标题,音乐名称,视频名称)又或者
又通过这个表去关联那些表呢
4),用JMS实现。发布订阅模式的应用。

想请问大家在面对这种功能需求的时候。会怎么来考虑?
贴张类似的需求的截图大家看看

 

 

 

0 请登录后投票
   发表时间:2008-04-13  
表结构及展示上用lllyq类似的架构应该可以满足需求;表可以采用对用户id取模的形式分拆。
另外,我觉得关键不在于展示,而是数据的抓取及合并。

好友信息对实时性的要求肯定不及主业务高,所以抓取这块肯定是通过异步处理,最好是具有分发机制的;但是JMS调用开销又比较大,即使用Lingo,也会多出几ms的开销,相比而言,文本或自定义通讯的机制开销会小一些。

信息合并目前没有好的想法(指类似一段时间内加了两好友,信息显示一条而非两条),只是每次有信息变更时比较下近期有无类似信息需要进行合并。不知大家有何更好的建议。
0 请登录后投票
论坛首页 Java企业应用版

跳转论坛:
Global site tag (gtag.js) - Google Analytics