【问题标题】:Unread message count in a PHP appPHP 应用中的未读消息计数
【发布时间】:2011-08-16 21:48:39
【问题描述】:

我目前正在开发一个简单的 PHP 应用程序,用户可以在其中相互发送消息。消息存储在 SQL 数据库中。我想在每个页面的菜单中统计未读消息,这样用户可以快速查看是否有新消息,而无需定期检查收件箱。

虽然这可能是一个容易解决的问题,但我不知道最好的方法是什么,就性能而言:

  1. 在每次页面加载时对未读消息执行普通 SQL COUNT()(立即通知更改,但可能会严重影响性能?)
  2. 做同样的事情,但将结果缓存 X 分钟(我们会造成烦人的延迟)
  3. 与 2. 相同,但仅在我们读取消息或向我们发送消息时更新(可能会占用大量 RAM/对磁盘造成压力,因为我们创建了一个持久条目/file per user : 我们不能将它存储在 $_SESSION 中,因为我们需要在另一个用户向我们发送消息时更新它)

我所有的解决方案都是基于服务器的,因为我对 JS 不是很熟悉。但是如果使用 JavaScript 存在更好的解决方案,那也没关系。

感谢您的帮助!

【问题讨论】:

    标签: php javascript sql message


    【解决方案1】:

    我建议第 4 次:

    向用户发送新消息后,您将更新memcache 中的计数器。您在客户端创建简单的 ajax 应用程序,每 X 秒发送一个请求。在服务器端,您只需检查是否有未读消息。在页面刷新时,您无需查询数据库,因为您从memcache 获取计数非常快。

    如果我在 DB 中遇到瓶颈,我会这样做(在 90% 的情况下,DB 是任何数据库驱动的应用程序中最少的部分)。

    这就是我们通常在高负载网站上所做的:我们试图避免任何 COUNTER 查询。如果不是,我们将数据库非规范化以将计数器作为另一列存储在适当的表中,例如如果您不能使用memcache,您可以将未读消息计数器存储为Users 表的列。

    【讨论】:

    • 是的,这似乎是最好的解决方案。但是,这意味着向我的应用程序添加另一个依赖项。谢谢你的回答!
    • 是的。维护起来有点困难,尤其是当您的应用程序正在成长时,但是 cmon! facebook 使用 MySQL 作为 key-value 存储并且主要依赖于memcache。处理高负载你将不得不牺牲一些东西。
    • @Artefact 和@Nemoden 听说过:“过早的优化是万恶之源”。在你的应用程序运行之前安装内存缓存和其他东西是不明智的。您应该首先以简单的方式构建您的应用,并在出现性能问题时更新您的应用。
    • @RJD22 我知道这个表达式。我读了一些文学作品。我还处理每天有超过 60 万用户和每秒超过 2000 次点击的应用程序。 SELECT COUNT(*) WHERE 到主服务器会导致性能问题。有人说我们正在处理未运行的应用程序吗?我想如果@Artefact2 问这个问题,他会关心性能。如果 SELECT COUNT() 一切正常,他为什么要不然呢?
    • @Nemoden 他仍在开发它。我最好在优化之前先运行一些简单的东西。甚至可能在他的情况下,计数是他最不担心的:P
    【解决方案2】:

    我会选择选项三,但我会添加 memcached 作为解决方案 4。

    【讨论】:

      【解决方案3】:

      执行未读的普通 SQL COUNT() 每个页面加载的消息(立即 通知更改,但可能会影响 性能差?)

      只要你有一个像样的表结构,COUNT() 是一个相当快的命令。我不会缓存这个特定的命令。相反,我会计算其他查询,以确保在向他们显示列表时只返回所需的数据。例如,如果您只需要摘录,我会确保执行以下操作:

      SELECT id, author, msgdate, substring(body, 0, 50) from table where recipient = ?
      

      而不是

      SELECT * from table where recipient = ?;
      

      【讨论】:

      • 我还是有点担心 COUNT() 的性能,因为一条消息可以有多个收件人,每个人都可能读过,也可能没有读过,等等。计算未读消息实际上涉及反加入…
      【解决方案4】:

      恕我直言。最好让客户端 ping 服务器并发送一个带有未读消息数量的 json。在 mysql 中计数应该很快,所以我认为没有理由不使用它。只需过滤聊天会话的结果。

      对于数据库部分。最好的方法是在你的数据库表中存储一个 new_message 并将其默认为 1,并在消息加载后将其设置为 0。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2018-08-28
        • 2015-08-06
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2022-07-14
        相关资源
        最近更新 更多