我正在为我们的页面(社交游戏类型)构建Facebook风格的通知系统,我现在正在研究设计这种系统的最佳方式。我对如何将通知推送给用户或类似的东西感兴趣(现在甚至)。我正在研究如何在服务器上构建系统(如何存储通知,存储它们的位置,如何获取它们等等。)
所以...我们有一些要求:
好的,我想的是我应该创建某种队列,我会在事件发生时存储它们。然后我会有一个后台工作(gearman?),它将查看该队列并根据这些事件生成通知。然后,此作业将在每个用户的数据库中存储通知(因此,如果事件影响10个用户,则会有10个单独的通知)。然后,当用户打开包含通知列表的页面时,我会为他读取所有这些通知(我们考虑将其限制为100个最新通知)并将它们组合在一起,然后最终显示它们。
我对这种方法感到担忧的事情:
那么您如何看待我提出的解决方案和我的担忧?如果您认为我应该提及其他与此相关的内容,请发表评论。
哦,我们在页面上使用PHP,但这不应该是我认为的一个重要因素。
答案 0 :(得分:168)
通知是关于某人(对象=事件,友情......)被某人(演员)改变(动词=添加,请求...)并报告给用户(主题)的通知。这是一个规范化的数据结构(虽然我使用过MongoDB)。您需要通知某些用户有关更改的信息。所以它是每用户通知..意味着如果涉及100个用户,则会生成100个通知。
╔═════════════╗ ╔═══════════════════╗ ╔════════════════════╗
║notification ║ ║notification_object║ ║notification_change ║
╟─────────────╢ ╟───────────────────╢ ╟────────────────────╢
║ID ║—1:n—→║ID ║—1:n—→║ID ║
║userID ║ ║notificationID ║ ║notificationObjectID║
╚═════════════╝ ║object ║ ║verb ║
╚═══════════════════╝ ║actor ║
╚════════════════════╝
(添加您认为合适的时间字段)
这基本上是为每个对象分组更改,因此您可以说“您有3个朋友请求”。每个演员的分组很有用,所以你可以说“用户James Bond在你的床上做了改变”。这也可以根据需要翻译和计算通知。
但是,由于对象只是一个ID,您需要通过单独的调用获取所需的所有对象的额外信息,除非对象实际更改并且您想要显示该历史记录(例如“用户将事件的标题更改为” ...“)
由于通知对于网站上的用户来说接近实时,我会将它们与nodejs + websockets客户端绑在一起,在更新被添加时,将更新推送到nodejs以获取更改。
答案 1 :(得分:27)
这实际上是一个抽象的问题,所以我想我们只是要讨论它,而不是指出你应该或不应该做什么。
以下是我对您的担忧的看法:
是的,通知系统很复杂,但不是很糟糕。您可以在建模和实施此类系统时采用许多不同的方法,它们可以具有从中等到高级的复杂性;
Pesonally,我总是试图让数据库驱动的东西。为什么?因为我可以保证完全控制正在发生的一切 - 但这只是我,你可以在没有数据库驱动的方法的情况下控制;相信我,你会想要控制那个案子;
让我举例说明一个真实的案例,这样你就可以从某个地方开始。在过去的一年里,我已经在某种社交网络中建模并实现了一个通知系统(当然不是像facebook那样)。我以前在那里存储通知的方式?我有一个notifications
表,我保留了generator_user_id
(生成通知的用户的ID),target_user_id
(很明显,不是吗?), notification_type_id
(引用具有通知类型的不同表),以及我们需要填充表的所有必要内容(时间戳,标志等)。我的notification_types
表曾与notification_templates
表关联,为每种类型的通知存储了特定模板。例如,我有一个POST_REPLY
类型,其模板类似于{USER} HAS REPLIED ONE OF YOUR #POSTS
。从那里开始,我只将{}
视为变量,将#
视为参考链接;
是的,效果应且必须才行。当您想到通知时,您会想到服务器从头到脚推送。如果你打算用ajax请求或其他什么来做,你将不得不担心性能。但我认为这是第二次关注;
我设计的那种模式当然不是唯一可以遵循的模式,也不是最好的。我希望我的回答至少会让你走向正确的方向。
答案 2 :(得分:8)
╔════════════════════╗
║notification ║
╟────────────────────╢
║Username ║
║Object ║
║verb ║
║actor ║
║isRead ║
╚════════════════════╝
这看起来很好,而不是有2个收藏。您可以通过用户名,对象和isRead查询以获取新事件(例如3个待处理的朋友请求,4个问题等...)
如果此架构存在问题,请与我们联系。
答案 3 :(得分:4)