论坛首页 Java企业应用论坛

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

浏览 66750 次
该帖已经被评为良好帖
作者 正文
   发表时间:2008-04-17  
mingsheng 写道

我此前参与的一个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实现。发布订阅模式的应用。

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

 

 

 


你上家公司的SNS产品是那个网站,呵呵,对好友动态这个功能分析的很全面.我也是刚着手来做这部分的开发..不过有点没弄明白.你们设计这个表是怎么能组织数据的呢?

0 请登录后投票
   发表时间:2008-08-21  
ithero 写道
呵呵.大家关注的更多还是开发呀.做架构的朋友没兴趣讨论么?
我弄了一个Friend_Dynamic表.大家看看

Dynamic_ID varchar(32);//主键
user_id varchar(32);//用户编号
Dynamic_Name  varchar(400);//动态消息名称
Dynamic_Desc varchar(3000);//动态消息说明
Dynamic_Thumb varchar(120);//动态消息截图
Dynamic_Type int(1);//动态类型 blog/comment/music/video
Create_time Date;

小弟最近也搞SNS呢.这里确实比较复杂.
要搞动态合并,
比如A和B加为好友,A和C加为好友
要合并为A 和 B,C加为好友这样的需求,这样的表结构实现起来太不容易了,
0 请登录后投票
   发表时间:2008-08-25  
小弟也在做好友动态信息的表结构 包括合并啊 用户管理动态信息的功能 真的不知道怎么实现 还要考虑性能方面的问题
看uchome 开心 校内都做的挺好 不知道怎么实现的 还请 高手 指点 一二。
0 请登录后投票
   发表时间:2008-08-25  
哈,我也来凑热闹。我的方法更简单:创建即生成。

用户采取动作的时候:上传图片--->生成html碎片(名字以类似log4j的样子增加)---->好友读取碎片。

好处:

1. 不通过数据库(这些资料并无实际意义)。
2. 遍历好友的相关目录就可以知道有无动作。
3
0 请登录后投票
   发表时间:2008-09-08  
ray_linn 写道
哈,我也来凑热闹。我的方法更简单:创建即生成。

用户采取动作的时候:上传图片--->生成html碎片(名字以类似log4j的样子增加)---->好友读取碎片。

好处:

1. 不通过数据库(这些资料并无实际意义)。
2. 遍历好友的相关目录就可以知道有无动作。
3


不知道你考虑这IO操作消耗没.对磁盘文件的管理也是个挑战.还有文件数限制,目录数的限制
0 请登录后投票
   发表时间:2008-10-03  
   我也来说说。肯定是需要一张专门记录操作动作的表,这个大家都比较认同。我个人觉得 id(主键),userid(用户id),content(需要在好友动态中显示的内容),type(类型 blog/comment/music/video),time(时间) 只要这几个就够了。

    前提只在好友动态中显示一定数量的好友最新信息(20条),不需要实现翻页。

    如何实现呢?就是在用户每次在新的专栏里执行新增操作时,除了往相应的业务表里写数据外,再向这个表里写一份。写的时候需要注意content的内容,直接将好友动态实际页面需要展示内容(html内容)拼好写入。这样在页面显示时,直接读取显示就行。

    可能有人会说,添加的栏目不同,好友动态信息显示内容不同,点击连接后所转向的页面也不相同呀。其实这个也很好解决。不同栏目在好友动态中显示的内容和样式不同,但是同一类型的内容显示的样式是相同的。而且我们每一个栏目中的操作肯定都是调用各自自己的方法,如blog就调用blog的action,comment就调用comment的action。这样我们只需在各自的action中增加一个写操作动作表的方法,这个方法直接将需要在页面展示的html内容拼好放入动作表的content中,每次执行一个新动作时调用这个方法就行了。
    这样在显示好友动态的时候直接从操作动作表中取一定数量的好友动作在好友动态中显示就行了。
0 请登录后投票
   发表时间:2008-10-10  
qq新版的消息中心,对于同一好友下不同类型的操作都能合并。这时候如果动态表包括有type的字段,就不太好对付了。
0 请登录后投票
   发表时间:2008-10-10  

最近也在做这个东西,刚才看了大家的讨论,终于想通了该怎么做了。现在给大家说说。

建一日志表,记录所有用户的操作日志,结构如下:

 

event(事件)

字段名称

类型

默认值

描述

ID

Int(10)

 

自增长,主键

userID

bigInt(20)

Not null

用户ID.索引

userName

Varchar(20)

Not null

用户姓名

content

text

Not null

内容

createTime

int(10)

Not null

创建时间.索引

content中保存用户的操作日志,也就是本贴讨论的重点。我采用的方法是前面有同学提到json方式。如:

{
 "blog":[
  {"id":1,"title":"安利台湾25周年庆"}
 ],
 "photo":[
  {"id":1,"title":"51韶关游"}
 ]
}

 

其中blog、photo代表某种应用的标识,可以无限添加。只要显示的时候能分析就行。里面的id和title就是内容的属性,结构自定。

 

 

 

至于新旧操作怎么合并,我是采取对event表的插入操作进行拦截实现的——我定义会员所有的操作均调用event的插入方法。

 

 

在拦截函数中,先select该会员的记录。如返回为空,则直接插入新记录。如返回记录,则将待插入数据与原数据进行合并。如待插入数据为:

{
 "blog":[
  {"id":2,"title":"我是谁"}
 ],
 "share":[
  {"url":"http://www.tudou.com","title":"土豆网 - 视频 - 播客 - 每个人都是生活的导演"}
 ]
}

 

则合并后的content为:

{
 "blog":[

  {"id":2,"title":"我是谁"}
  {"id":1,"title":"安利台湾25周年庆"},
 ],
 "photo":[
  {"id":1,"title":"51韶关游"}
 ],
 "share":[
  {"url":"http://www.tudou.com","title":"土豆网 - 视频 - 播客 - 每个人都是生活的导演"}
 ]
}

 

然后使用update方法即可。

 

 

 

但这里有一个问题就是,如果用户每天或每个数据表清理间隔中(如我的系统定义为2天)都有操作产生,则会累积很巨大的历史记录,我初步考虑是在拦截方法中进行过滤。而如果用户在2天内没有新的操作产生,则会被我另外定义的数据清理任务删除记录。

0 请登录后投票
   发表时间:2008-10-10  
我计划实现的效果,qq消息中心截图
  • 大小: 38.3 KB
0 请登录后投票
   发表时间:2008-10-15  
看了大家的回复,好像都集中在数据库表结构的讨论
能不能变通个方法呢?比如用memcache等缓存,用户id为主键,所发生的动作存储一个list
0 请登录后投票
论坛首页 Java企业应用版

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