使用PHP和MySQL实现通知/新闻源

4

我一直在开发一个复杂的PHP系统,将社交网络的元素融入到一个封闭的人群中。我有几个模块,包括照片和视频库、完整的评论系统、私信、带GUI的个人邮件等等。

我的问题是,无论我如何努力,似乎都不能以有效的方式设计通知和新闻订阅后端,就像Facebook所拥有的那样。这些模块基本上都是事件驱动的,因此将它们连接到通知系统不应该是一个问题。希望集体头脑风暴能解决我的问题。

在这篇文章中,我只会针对通知部分提出我的问题(如果我也包括新闻订阅,这篇文章将变得非常冗长和混乱)。

以下是我第一次MySQL表草案:

notificationID
主键

notificationModule
模块类型外键——照片、视频、评论、消息

notificationConstructor
元素的外键(其类型为“notificationModule”),触发了此通知的创建

notificationUser
此通知所针对的用户

notificationTime
通知创建时间

notificationFlag
通知已读标志

可能存在的问题/冲突

  • 当一个用户评论两个不同用户已经评论过的照片时,会触发三个通知吗?一个是给上传照片的用户,另外两个是给每个评论者的?(影响notificationUser
    • notificationTime是创建时间。根据上述问题,如果我们不创建新通知,这个字段应该被notificationUpdateTime替换或与其并存吗?

我希望代码复杂度更低,数据库效率更高。试图将数据库层与代码层分离在网站的这一部分让我感到困惑 :(

我欢迎所有的关注和想法。


我只是想确保我清楚你在问什么。你是在建议将数据库用作一种通知队列吗?换句话说,让事件将通知放入表中,然后有一个单独的脚本或进程来消耗它们,从表中删除它们并将它们传递出去?如果是这样,那似乎是一种合理高效且可扩展的解决问题的方式。 - Ryan Ballantyne
是的,这正是我所提议的。尽管我的担忧在于处理通知的脚本的效率。最好是有一个脚本,根据数据库中的条目查找要通知的用户,还是直接向一个用户发送这些通知。如果已经有10个人对某个事物进行评论,那么这意味着需要向数据库插入10个新条目。 - Spyros
2个回答

1

经过几天的休息,我已经改变了对新闻提要和通知系统的思考方式。我采取的方法是每个事件(评论、标签等)都会触发一个有关两个用户的单个通知,即演员和通知对象用户(例如打标签的人和被打标签的人)。另一方面,新闻提要将从通知条目中合理地获取最近的条目(假设它不是私人信息),并建立提要。这可能会对数据库造成压力,但在最多100个用户的情况下,我认为这不会成问题。感谢Ryan的意见 :)


1
有两种方法来处理新闻订阅:
  • 按写入进行扇出
  • 按阅读进行扇出
你正在使用按写入进行扇出的方法。在这种情况下,您为每个相关用户生成一个新的单独活动。
这种方法可能会很快失控,特别是如果您允许用户拥有无限数量的关注者。每当发生频繁的活动时,您都必须在数据库中保存1000多个关注者的新条目。
当您添加组和不同类型的受众时,事情变得更加复杂。如果您现在只想向A组中的人广播活动而不是B组中的人(例如,您创建了一个状态并希望限制查看者),会发生什么?当您想要向A组和B组广播时,但是A组和B组中都有您不希望接收相同活动的用户时会发生什么?如果您想在创建后更改活动的可见性怎么办?
这在按写入进行扇出的方法中实际上不太可能,或者至少非常困难。这就是为什么我更喜欢后者——按阅读进行扇出的方法。
考虑一下这个:
一个用户有一组与其ID相关联的新闻订阅频道。这些频道的形式为{{ object_name }}: {{ object_id }}。您可以拥有新闻和通知的单独设置,以便您可以取消对一个对象的通知而不将其从您的新闻订阅中删除。
当用户注册以接收来自对象的更新时,他们正在将与该对象关联的频道添加到其频道列表中。您可以使用简单的Redis集合。例如,如果我加入事件#1,则将event:1添加到我的频道列表中。
当事件#1上的属性更改时,仅创建一个新活动。此活动具有称为“observer”的字段,该字段是其可见性的频道名称。在这种情况下,观察者是“event:1”。
当用户拉取其活动源时,他们首先获取已订阅频道的列表。然后,他们检索其中观察者位于其频道列表中的所有活动源项。
另外:

我不太确定如何将其转换为通知系统。使用“读取扇出”方法,我有一组用于通知的频道,如上所述。当对象上的属性更改时,我会向数据库写入新通知,所有订阅用户都会收到。唯一的问题是:我该如何按用户逐个读取通知?我还没有解决这部分。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接