You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

PHP+SQL环境下,如何关闭关注用户新帖子的通知提醒?

嘿,针对你这个基础通知系统的问题,我来梳理几个实用的方案,帮你搞定点击通知后关闭提醒的需求:

核心解决方案梳理

方案一:创建独立的通知表(最推荐,扩展性强)

这是行业里最通用的做法,毕竟你以后大概率会扩展更多通知类型(比如评论提醒、点赞提醒),独立的通知表能完美适配这类需求。

  • 表结构参考:
    CREATE TABLE user_notifications (
        id INT PRIMARY KEY AUTO_INCREMENT,
        user_id INT NOT NULL, -- 接收通知的用户,比如Ed的ID=3
        source_type VARCHAR(50) NOT NULL, -- 通知来源类型,比如"post"
        source_id INT NOT NULL, -- 对应帖子的ID
        is_read BOOLEAN DEFAULT FALSE, -- 是否已读,默认未读
        created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
        FOREIGN KEY (user_id) REFERENCES users(id),
        FOREIGN KEY (source_id) REFERENCES posts(id)
    );
    
  • 点击通知后的操作:
    当Ed点击“6条新帖子”的提醒时,执行批量更新,把这6条帖子对应的通知记录的is_read设为true:
    UPDATE user_notifications 
    SET is_read = true 
    WHERE user_id = 3 
      AND source_type = 'post' 
      AND source_id IN (帖子ID1, 帖子ID2, ..., 帖子ID6);
    
  • 未读数量查询:
    每次页面加载时,统计该用户未读通知数:
    SELECT COUNT(*) FROM user_notifications 
    WHERE user_id = 3 AND is_read = false;
    
    这样页面就能实时显示最新的未读数字了。

方案二:用户-帖子已读关联表(轻量型,仅针对帖子场景)

如果你的系统暂时只需要帖子通知,不想搞复杂的通知表,可以用这个轻量方案:

  • 创建关联表:
    CREATE TABLE user_post_read (
        user_id INT NOT NULL,
        post_id INT NOT NULL,
        PRIMARY KEY (user_id, post_id),
        FOREIGN KEY (user_id) REFERENCES users(id),
        FOREIGN KEY (post_id) REFERENCES posts(id)
    );
    
  • 点击通知后的操作:
    把Ed的ID和这6条帖子ID批量插入到这个表(如果已存在就忽略):
    INSERT INTO user_post_read (user_id, post_id)
    VALUES (3, 帖子ID1), (3, 帖子ID2), ..., (3, 帖子ID6)
    ON DUPLICATE KEY UPDATE user_id = user_id; -- 重复时不做操作
    
  • 未读数量查询:
    统计Ed关注的用户发布的帖子中,不在已读表的数量:
    SELECT COUNT(*) FROM posts p
    JOIN user_follows uf ON p.user_id = uf.following_id
    WHERE uf.follower_id = 3 -- Ed是关注者
      AND NOT EXISTS (
          SELECT 1 FROM user_post_read upr 
          WHERE upr.user_id = 3 AND upr.post_id = p.id
      );
    
    这个方案比通知表轻量,但扩展性差,以后加其他通知类型就得再加新表。

方案三:前端临时标记(仅临时演示用,不推荐生产环境)

如果只是做个简单Demo,不想动数据库,可以用前端的localStorage来存已读帖子ID:

  • 点击通知时,把这6条帖子ID存入localStorage:
    const readPosts = JSON.parse(localStorage.getItem('readPosts')) || [];
    const newReadPosts = [...readPosts, ...[帖子ID1, 帖子ID2, ..., 帖子ID6]];
    localStorage.setItem('readPosts', JSON.stringify([...new Set(newReadPosts)])); // 去重
    
  • 页面加载时,过滤已读帖子计算未读数:
    从后端拿到Ed关注用户的所有帖子后,排除localStorage里的已读ID,剩下的数量就是未读数。
    缺点很明显:换设备、清缓存就会丢失已读状态,数据不同步,只适合临时用。
对你疑问的逐一解答
  • 点击通知后如何关闭提醒?:
    对应上面的方案,要么后端标记已读/插入已读记录,更新未读数;要么前端存已读状态,页面上把提醒数字改成0。
  • 是否需要创建通知表?:
    如果想长期维护、扩展通知功能,非常推荐创建,这是行业通用做法。如果只是临时的帖子通知,用方案二的关联表也可以。
  • 是否需为帖子添加状态字段?:
    绝对不需要!帖子的已读状态是用户维度的,不是帖子本身的属性(总不能说一个帖子被Ed读了,就变成“已读状态”对所有用户生效吧),所以必须把已读状态存在用户和帖子的关联表,或者独立的通知表中。
  • 是否需要重新执行SQL查询?:
    需要的。点击通知标记已读后,最好重新查询一次未读数量,更新页面上的提醒数字,确保数据和后端一致。当然前端也可以直接把数字改成0,但如果有其他设备同时操作,可能会有数据不一致的情况,所以后端查询更可靠。

内容的提问来源于stack exchange,提问作者joe

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.19 10:36:46