我很想听听你对实现社交活动流的最佳方式(Facebook就是最著名的例子)的看法。涉及的问题/挑战有:
不同类型的活动(张贴,评论..)
不同类型的对象(帖子,评论,照片..)
1-n个不同角色的用户(“用户x回复了用户y对用户Z帖子的评论”)
同一活动项的不同视图(“您评论了..”vs。“你的朋友x评论”vs。"用户x评论说.."3个“评论”活动的表示)
. .还有更多,特别是如果你把它提高到一个高度复杂的水平,比如,把几个活动项目合并成一个(“用户x, y和z评论了那张照片”)。
任何关于模式、论文等关于最灵活、有效和强大的方法来实现这样一个系统、数据模型等的想法或建议都将受到欢迎。
尽管大多数问题与平台无关,但我最终有可能在Ruby on Rails上实现这样一个系统
我昨天开始执行一个这样的系统,这就是我要做的…
我创建了一个带有属性Id、ActorId、TypeId、Date、ObjectId和附加细节键/值对哈希表的StreamEvent类。这在数据库中由一个StreamEvent表(Id, actid, TypeId, Date, ObjectId)和一个StreamEventDetails表(StreamEventId, DetailKey, DetailValue)表示。
ActorId、TypeId和ObjectId允许捕获一个Subject-Verb-Object事件(以及稍后查询)。每个操作都可能导致创建多个StreamEvent实例。
然后,我为StreamEvent的每种类型的事件创建了一个子类,例如LoginEvent, PictureCommentEvent。这些子类中的每一个都有更多上下文特定的属性,如PictureId, ThumbNail, CommenText等(事件所需的任何属性),这些属性实际上存储为hashtable/StreamEventDetail表中的键/值对。
当从数据库中提取这些事件时,我使用一个工厂方法(基于TypeId)来创建正确的StreamEvent类。
StreamEvent的每个子类都有一个Render(context As StreamContext)方法,该方法根据传递的StreamContext类将事件输出到屏幕。StreamContext类允许基于视图的上下文设置选项。以Facebook为例,主页上的信息流会列出参与每个行动的每个人的全名(以及他们个人资料的链接),而查看朋友的信息流,你只能看到他们的名字(但其他参与者的全名)。
我还没有实现一个聚合提要(Facebook家),但我想我会创建一个AggregateFeed表,其中有字段UserId, StreamEventId,这是基于某种“嗯,你可能会发现这个有趣的”算法。
任何意见都将非常感激。
事件流最大的问题是可见性和性能;您需要将显示的事件限制为只显示该特定用户感兴趣的事件,并且需要保持整理和识别这些事件所需的时间。我建立了一个小型的社交网络;我发现,在小范围内,在数据库中保留“事件”表是可行的,但在中等负载下就会出现性能问题。
对于较大的消息流和用户,最好使用消息传递系统,将事件作为消息发送到单个配置文件。这意味着您不能很容易地订阅人们的事件流,也不能很容易地查看以前的事件,但是当您需要为特定用户呈现流时,您只是呈现了一小组消息。
I believe this was Twitter's original design flaw- I remember reading that they were hitting the database to pull in and filter their events. This had everything to do with architecture and nothing to do with Rails, which (unfortunately) gave birth to the "ruby doesn't scale" meme. I recently saw a presentation where the developer used Amazon's Simple Queue Service as their messaging backend for a twitter-like application that would have far higher scaling capabilities- it may be worth looking into SQS as part of your system, if your loads are high enough.
我昨天开始执行一个这样的系统,这就是我要做的…
我创建了一个带有属性Id、ActorId、TypeId、Date、ObjectId和附加细节键/值对哈希表的StreamEvent类。这在数据库中由一个StreamEvent表(Id, actid, TypeId, Date, ObjectId)和一个StreamEventDetails表(StreamEventId, DetailKey, DetailValue)表示。
ActorId、TypeId和ObjectId允许捕获一个Subject-Verb-Object事件(以及稍后查询)。每个操作都可能导致创建多个StreamEvent实例。
然后,我为StreamEvent的每种类型的事件创建了一个子类,例如LoginEvent, PictureCommentEvent。这些子类中的每一个都有更多上下文特定的属性,如PictureId, ThumbNail, CommenText等(事件所需的任何属性),这些属性实际上存储为hashtable/StreamEventDetail表中的键/值对。
当从数据库中提取这些事件时,我使用一个工厂方法(基于TypeId)来创建正确的StreamEvent类。
StreamEvent的每个子类都有一个Render(context As StreamContext)方法,该方法根据传递的StreamContext类将事件输出到屏幕。StreamContext类允许基于视图的上下文设置选项。以Facebook为例,主页上的信息流会列出参与每个行动的每个人的全名(以及他们个人资料的链接),而查看朋友的信息流,你只能看到他们的名字(但其他参与者的全名)。
我还没有实现一个聚合提要(Facebook家),但我想我会创建一个AggregateFeed表,其中有字段UserId, StreamEventId,这是基于某种“嗯,你可能会发现这个有趣的”算法。
任何意见都将非常感激。