SNS网站一般都有这么一个功能:feed或者叫做新鲜事之类的
之前在我们自己的网站也做了类似的一个功能,当时让人最郁闷的就是数据量的问题,上网搜了下,大部分结构都是类似。
我当时设计了这么一种简单的机制,数据量相对较小,但是运算复杂,并且限制较多:
1)feed字典表:
feeds
(
id,
event_type: int, //事件类别:写日记,上传照片,成为好友等等
share_type: int, //公开类别:私密信息(收到新消息之类的),公开信息等
msg:string //feed消息模板
)
2)user_feed表,用于保存用户操作的每个:
user_feeds
(
id,
feed_id: int, //feed字典表所属ID
user_id: int, //用户名
share_type: int, //公开类别
params: string,//参数,可以是jason格式
attach_text: string,//附加说明
created_at: datetime
updated_at: datetime
)
3)user_watch表,用于保存用户对哪些好友进行关注,关注哪种类别消息:
user_watches
(
id,
user_id, //用户ID
friend_id, //好友ID
watch_type
)
在这种结构下,我们采用的方法就是连接查询并生成该用户(current_account)可见好友的feeds:
select uf.*
from user_feeds uf,user_watches uw
where uf.user_id = uw.friend_id and uf.user_id = (current_account_id) and uf.share_type = (public)
个人产生私有feeds
select * from user_feeds where user_id = (current_account_id) and uf.share_type = (private)
在页面层再调用feed render方法:
render_feed(user_feed) 来根据feed类别来渲染不同的显示。
然后做页面层的cache,每10分钟或者20分钟刷新一次,并且每一段时间清空一次过期的user_feeds表。
目前这种机制我们使用的还没有遇到太多问题,在我们网站还是百万量级的存储。
这种方式最大的缺点就是无法删除feed,并且feed需要重复运算。优点就是存储空间小。
当时想到一种支持删除feed的方法就是做一个feed_watches表,用于存储某个查看某个user_feed的状态,
目前没有实现。
目前其他网站的做法貌似都是使用了一张表专门存储某个用户收到的feed。
这个表会非常大,每天产生100万个事件,如果平均每个人有20个好友,那么将会有两千万条消息。
假设要保存10天的数据,将会有两亿多条数据,只能通过分表来解决。
不知道Facebook这些公司咋搞的~