社交网络通知逻辑

Posted

技术标签:

【中文标题】社交网络通知逻辑【英文标题】:Social network notifications logic 【发布时间】:2014-09-14 02:59:22 【问题描述】:

我正在开发某种社交网络。类似于twitter/instagram,有用户,可以互相关注,发帖,写cmets,点赞。

我已经实现了一个通知系统,用户可以在其中获取有关他关注的人的活动的信息(他们喜欢什么和评论什么)。

我为此使用了 mysql 查询。 这是查询的简化版本:

SELECT t.type, t.param1, t.param2, t.date_time FROM (
    SELECT 'like' as type,
    likes.user_id as param1,
    likes.user_name as param2,
    likes.date_time as date_time,
    FROM likes
    WHERE (SOME CONDITION GOES HERE)

    UNION ALL

    SELECT 'comment' as type,
    comments.user_id as param1,
    comments.user_name as param2,
    comments.date_time as date_time,
    FROM comments
    WHERE (SOME CONDITION GOES HERE)
) as t ORDER BY t.date_time ASC

一切正常。

我下一步要做的是向用户显示他收到了多少新通知。

为此,我有一个解决方案,我想问您它是否可行/有效,或者您是否知道如何更好地实施它。

所以,解决方案是: 我将在用户表中创建一个字段“total_notifications”。 每次用户访问网站时,我都会获取 mysql 计数所有通知和 如果通知多于用户字段,我会将它们之间的差异显示为“新”。

换句话说,每次用户访问网站时都会调用上面编写的那种查询,但SELECT t.type 将不是SELECT count(*)

我知道这对数据库来说是一项繁重的工作,所以有没有其他解决方案或者这样可以吗?

【问题讨论】:

【参考方案1】:

好吧,创建一个名为 notification 的新表,存储用户 id、通知类型、内容、seen 字段(bool)

然后,当任何事情发生时,将所需的值添加到此表中。

然后在用户检查网站时做一个

SELECT COUNT(*) WHERE user_id= current user id AND seen = 0.

然后将所有这些字段的值设为 1,以将它们标记为用户可见。

我希望我能理解你的问题。

【讨论】:

【参考方案2】:

首先,带有 WHERE 的 SELECT count(*) 将扫描整个表/索引以返回计数。如果表有一个适合查询的覆盖索引,它基本上会非常快,因为它只扫描索引。否则,它会扫描整个表然后非常糟糕。对于您的 total_notifications 问题,您必须进行 2 次查询并比较值以获得“新”。问题是你只想得到“新的”,它假设是所有活动的一小部分,但如果你明白我的意思,它必须获取这个查询中的所有活动行。我建议您添加一个新字段名称“status”,其值如(“new”、“read”)。你也应该在覆盖索引中索引这个字段。为了获得“新”,您只能运行 1 个查询来过滤具有状态 ='new' 的行。有一个好的索引,这个查询会非常快,它假设扫描索引的一小部分。

SELECT count(*) as t_new FROM (
    SELECT 'like' as type
    FROM likes
    WHERE (SOME CONDITION GOES HERE) AND status='New'

    UNION ALL

    SELECT 'comment' as type
    FROM comments
    WHERE (SOME CONDITION GOES HERE) AND status='New'
) as t

我相信您甚至可以通过将“date_time > timestamp_of_last_activity_user_seen”添加到 WHERE 来改进此查询。

【讨论】:

由于您没有特别提及,您应该将状态创建为枚举,以便与 char/varchar(扫描时间更长)相比,将其存储为字节值。 是的,作为 ENUM 的状态更好,谢谢@trick。更适合索引 非常感谢您的回复。我理解你,但你看,所有这些活动都是伪通知,表中的这些记录(cmets,likes)只是用户的活动,不能有“新”或“读”这样的字段,因为如果一个用户阅读它们将影响关注此用户的所有其他用户,并且他们不会收到这些新通知。另一种方法是按照 Ramy Tamer 的建议创建表“通知”(谢谢顺便说一句),但我认为这对 DB 来说更重,因为如果一个用户进行活动,我需要为每个关注他的人创建记录. 所以它不仅会增加数据库数据的大小,还会增加它。 @wolfdale 我现在看到你的问题了。您可能需要每个用户的每个表,其中包含 activity_id 和状态。 InnoDB 最多允许 4B 表,应该可以工作并且负载性能应该没问题。读取时将数据交易与性能相乘。不过我建议你也试试 redis。每个用户都有自己的 redis 列表,这就是 Twitter 的做法,他们有一个扇出进程,可以写入所有后续用户的 redis 列表。

以上是关于社交网络通知逻辑的主要内容,如果未能解决你的问题,请参考以下文章

社交网络场景中的 Azure 通知中心最佳实践

MySql vs NoSql - 社交网络评论和通知数据结构和实现

高度可定制的社交网络平台

显示通知逻辑

怎么使用使用 Spring Social 连接社交网络

在新的社交网络中开放社交[关闭]