2015-02-07 125 views
0

我設計了一個數據庫模式,允許使用Facebook風格的消息傳遞系統(沒有能夠編輯消息的功能)。那就是:我在模式中做錯了什麼?

enter image description here

我的想法是用戶將消息發送到對話,而不是給其他用戶。這樣,用戶訂閱對話,允許多種用戶風格的聊天。

A conversation就像一個房間。如果用戶bob和用戶joe開始通話,如果一個通話不存在,將會創建一個通話。每當'鮑勃'和'喬'說話他們的消息總是會有相同的conversation_id。這將允許我通過收到conversation_id的所有消息來返回他們的所有通信。

多個用戶可以是conversation的一部分。 conversation_users表存儲conversation_iduser_id,它允許我查詢表得到All users who have the conversation_id X

我遇到的問題是我想查詢:Give me the conversation_id used by Joe and Bob,所以我可以用這個conversation_id返回'Joe'和'Bob'之間的所有消息。

我怎麼能做到這一點?我想我已經錯過了一些重要的模型,這使得它看起來比需要的更復雜。但我看不到什麼。

回答

1

您需要由Joe和Bob使用的conversation_id值的交集。

如何獲取Joe使用的conversation_id值?

  SELECT cu.conversation_id 
      FROM Users u 
      JOIN Conversation_Users cu ON u.id = c.user_id 
      WHERE username = 'Joe' 

對Bob做同樣的處理,給你兩個子查詢。驗證這些;確保它們正常工作。

然後你這樣做:

SELECT cu.conversation_id 
    FROM Users u 
    JOIN Conversation_Users cu ON u.id = c.user_id 
WHERE username = 'Joe' 
    AND cu.conversation_id IN 
     (
      SELECT cu.conversation_id 
      FROM Users u 
      JOIN Conversation_Users cu ON u.id = c.user_id 
      WHERE username = 'Bob' 
     ) 

,讓你涉及兩個用戶的交談ID列表。 編輯 A JOIN也可以像這樣處理這個邏輯。

SELECT a.conversation_id 
    FROM (SELECT cu.conversation_id 
      FROM Users u 
      JOIN Conversation_Users cu ON u.id = c.user_id 
     WHERE username = 'Joe' 
      AND cu.conversation_id 
     ) a 
    JOIN ( SELECT cu.conversation_id 
      FROM Users u 
      JOIN Conversation_Users cu ON u.id = c.user_id 
      WHERE username = 'Bob' 
     ) b ON a.conversation_id = b.conversation_id 

這些查詢的第一個可以放在MySQL視圖中,而第二個查詢不能。哪一個更快?很難知道沒有嘗試他們兩個。

可能有多個這樣的對話。如果你只想要一個,你必須弄清楚如何選擇它。

你還沒有離開你的模型。這只是因爲這種交集操作的邏輯很微妙,因爲MySQL沒有INTERSECTION運算符。

+0

這是完美的。我需要刷我的SQL,因爲如果沒有你的建議,我需要一段時間才能在單個查詢中弄清楚。感謝Ollie。 – 2015-02-07 16:02:19

+0

奧利,一個簡單的問題,這可以通過一個Inner Join來完成嗎?如果是這樣更快? – 2015-02-07 22:53:55

+0

感謝Ollie。刪除用戶名,我重寫你的第一個像這樣:https://gist.github.com/jamesjeffery/f766813d5efcd041561e ...不知道是否這樣做,只是現在檢查您的編輯。 – 2015-02-07 23:46:10