确定论坛中的未读项目

Can*_*ICA 4 php mysql forum

使用PHP和MySQL,我有一个我正在尝试构建的论坛系统.我想知道的是,我如何设置它,以便当用户阅读论坛条目时,无论他们在哪个论坛,它都显示为该用户的JUST,直到有人在其上发帖.

目前,对于每个线程,我有一个带有PostID的表,并且具有发布它的UserID,将其链接到的ThreadID,实际的Post(作为Text),然后是它发布的日期/时间.

对于每个论坛中的线程列表,有threadID(主键),ThreadName,它所属的ForumID,NumPosts,NumViews,LastPostDateTime和CreateDateTime.有帮助吗?

bob*_*nce 8

传统的解决方案是连接表,其内容如下:

CREATE TABLE topicviews (
    userid INTEGER NOT NULL,
    topicid INTEGER NOT NULL,
    lastread TIMESTAMP NOT NULL,
    PRIMARY KEY (userid, topicid),
    FOREIGN KEY (userid) REFERENCES users(id),
    FOREIGN KEY (topicid) REFERENCES topics(id)
);
Run Code Online (Sandbox Code Playgroud)

每次读取主题时都会更新lastread.显示主题列表时,如果topics.lastupdated是> topicviews.lastread,则会有新帖子.

传统的解决方案是垃圾,会杀死你的数据库!不要这样做!

第一个问题是,对每个主题视图的写入很快就会使数据库服务器在繁忙的论坛上瘫痪,特别是在只有表级锁的MyISAM表上.(不要使用MyISAM表,除了全文搜索之外的所有内容都使用InnoDB).

您可以稍微改善这种情况,只需在主题中读取实际新消息时写入最后读取时间.如果topic.lastupdated <topicviews.lastread,则无法通过更新值获得任何好处.即便如此,在频繁使用的论坛上,这可能是一种负担.

第二个问题是组合爆炸.每个用户每个主题一行很快就会加起来:只有一千个用户和一千个主题,你可能有一百万个topicview行要存储!

您可以通过限制每个用户记住的主题数量来改善这种情况.例如,当它超过某个年龄时,您可以从视图表中删除任何主题,并假设所有旧主题都是"已读".这通常需要在后台完成清理任务.

其他不太密集的方法包括:

  • 每个论坛只存储一个最后读取时间
  • 只存储整个站点上每个用户的一个lastvisit时间,这将显示为"新"仅自用户上次访问(会话)以来更新的内容
  • 根本不存储任何lastread信息,但包括主题URL本身的最后更新时间.如果用户的浏览器最近看过该主题,它将记住该URL并将其标记为已访问.然后,您可以使用CSS将访问过的链接设置为"不包含新消息的主题".