Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/symfony/6.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Php 社交网络通知逻辑_Php_Mysql_Notifications_Logic_Social - Fatal编程技术网

Php 社交网络通知逻辑

Php 社交网络通知逻辑,php,mysql,notifications,logic,social,Php,Mysql,Notifications,Logic,Social,我在一种社交网络上工作。它类似于twitter/instagram,有用户,他们可以互相关注、发帖、写评论和点评 我已经实现了一个通知系统,用户可以从中获取他所关注的人的活动信息(他们喜欢什么和评论什么) 我使用了mysql查询。 这是查询的简化版本: SELECT t.type, t.param1, t.param2, t.date_time FROM ( SELECT 'like' as type, likes.user_id as param1, likes.use

我在一种社交网络上工作。它类似于twitter/instagram,有用户,他们可以互相关注、发帖、写评论和点评

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

我使用了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
一切正常

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

对于这一点,我有一个解决方案,我想问你它是否可以/有效,或者你是否知道如何更好地实施它

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

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


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

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

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

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

SELECT COUNT(*) WHERE user_id= current user id AND seen = 0.
然后使所有这些字段的“可见”值等于1,以将它们标记为用户可见


我希望我理解你的问题

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

我相信你甚至可以通过在WHERE中添加“date\u time>timestamp\u of_last\u activity\u user\u seen”来改进这个查询。

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