Mysql php私密邮箱就像邮件系统一样

时间:2015-03-29 13:14:05

标签: php mysql database-connection messaging

我正在为我的应用构建一个小型消息传递系统,主要的想法是拥有2个表。 表1消息

Id,sender_id,title,body,file,parent_id

这是存储消息的地方,与谁分开将接收消息以允许多个收件人。

父母如果是回复则链接到父消息,而文件是用于存储附加到消息的单个文件的blob

表2 message_users

Id,thread_id,user_id,is_read,stared,deleted

将父线程链接到目标用户,

现在让一个用户可以查看我可以做的未读消息的数量

Select count(*) from message_users where user_id = 1 and is_read is null

要计算收件箱中所有邮件的数量,我可以

Select count(*) from message_users where user_id = 1;

问题是如何在单个优化查询中结合两者?

3 个答案:

答案 0 :(得分:2)

因此,您正在尝试实现满足一个条件的总行数以及满足额外条件的总行数:

|---------|---------|
| total   | unread  |
|---------|---------|
| 20      | 12      |
|---------|---------|

因此需要具有以下形式的表格:

SELECT A total, B unread FROM message_users WHERE user_id=1

A非常简单,您已经或多或少地拥有它:COUNT(Id)

B稍微复杂一些,可能采用SUM( IF(is_read IS NULL,1,0) )形式 - 每次is_read不为null时加1;条件取决于您的数据库细节。

B可能如下:COUNT(CASE WHEN is_read IS NULL THEN 1 END) unread - 这就是说'当is_read为空时,计算另一个1&#39 ;;条件取决于您的数据库细节。

总计:

SELECT COUNT(Id) total, COUNT(CASE WHEN is_read IS NULL THEN 1 END) unread FROM message_users WHERE user_id=1

或者:

SELECT COUNT(Id) total, SUM( IF(is_read IS NULL,1,0) ) unread FROM message_users WHERE user_id=1

就优化而言,我不知道可能比这更快的查询。 (如果确实存在,我很想知道它!)如果你遇到性能问题,可能有办法加快速度:

  • 检查索引:使用内置工具EXPLAIN和一些阅读等。
  • 使用缓存和/或预先计算该值并将其存储在其他位置 - 例如对unread_messages设置字段user并直接获取此值。显然,需要进行一些写入失效,或者确实需要运行一些服务来保持这些值是最新的。有很多方法可以实现这一点,MySQL中的工具,自己动手等等。
  • 简而言之,从需求和一些真实数据开始优化。 (我的查询需要0.8秒,我需要0.1秒内的结果,它们需要在100%的时间内保持一致 - 我怎样才能实现这一点?)然后你可以调整和试验SQL ,服务器运行的硬件(可能?),在不同点缓存/预先计算等。

答案 1 :(得分:1)

在MySQL中,当你计算一个字段时,它只计算该字段的非空出现次数,所以你应该可以这样做:

SELECT COUNT(user_id), COUNT(user_id) - COUNT(is_read) AS unread
    FROM message_users 
    WHERE user_id = 1;

未经测试,但它应该指向正确的方向。

答案 2 :(得分:1)

您可以将sum与CASE WHEN子句一起使用。如果is_read为空,则会将+1添加到总和中,否则为+0

SELECT count(*),
  SUM(CASE WHEN is_read IS NULL THEN 1 ELSE 0 END) AS count_unread
  FROM message_users WHERE user_id = 1;