簡體   English   中英

Mysql PHP的私人電子郵件,如消息傳遞系統

[英]Mysql php private email like messaging system

我正在為我的應用程序構建一個小型消息傳遞系統,主要思想是擁有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;

問題是如何在單個優化查詢中將兩者結合?

因此,您正在嘗試實現將滿足一個條件的總行和滿足額外條件的總行數:

|---------|---------|
| 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為null時,再計數1”。 條件將取決於您的數據庫詳細信息。

總共:

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和一些閱讀資料等。
  • 使用緩存和/或預先計算該值並將其存儲在其他位置-例如,針對user unread_messages字段, unread_messages直接獲取該值。 顯然,將需要進行一些寫無效操作,或者實際上需要運行某些服務以使這些值保持最新。 有很多方法可以做到這一點,例如MySQL中的工具,自己動手等等。
  • 簡而言之,從需求和一些實際數據開始進行優化。 我的查詢需要0.8s,我需要0.1s的結果,並且它們必須在100%的時間內保持一致-我該如何實現? )然后您可以對SQL和服務器運行的硬件進行調整和試驗(也許?),在不同點緩存/預先計算等。

在MySQL中,當您計算一個字段時,它只計算該字段的非null出現次數,因此您應該能夠執行以下操作:

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

未經測試,但它應該為您指明正確的方向。

您可以將sum與CASE WHEN子句一起使用。 如果is_read為null,則將+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;

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM