2011-01-18 35 views
1

我有這樣的表設置:
消息發送到一組用戶。mysql:設計實踐

該消息被放入parent_message
本表包含id | sender_id | date

被放入child_message表是該組中的每個發送的消息
此表包含id | parent_id | message | date_sent

當答覆是收到它被放入reply_message
此表包含id | child_id | message | date_received

現在我對這個設置有幾個問題。


1)每次頁面加載時,我需要顯示每條父消息有多少個子消息。
您是否將一列添加到名爲child_count的parent_message表中或在查詢中解決。
爲什麼,爲什麼不呢?

實施例的查詢

select *, 
count(select parent_id from child_message c where c.parent_id = p.parent_id) child_count 
from parent_message; 

2)如果用戶選擇,他們可以查看所有的應答消息到父消息。
你會將parent_id添加到應答reply_message表中還是在查詢中解決?
爲什麼,爲什麼不呢?

例子查詢

select * from reply_message 
where child_id in(select id from child_message where parent_id = '66') 

回答

0

我會說這非常取決於消息的數量。如果系統中有一百萬條消息,則加入child_message可能會變得非常昂貴。在這種情況下,向父表添加child_count可能對您的性能有所幫助。你的第二個用例也一樣。當然,這是對數據的一些非規範化,所以如果您的系統允許重新塑造主題和回覆(如分割主題),那麼您必須在這種情況下進行額外的簿記。

將創建索引表,持有你所需要的信息,並以異步方式離線更新它們,如果你不需要的信息是100%準確例如所有的時間另一種方法

表message_counts(PARENT_ID,CHILD_COUNT)

然後當新的消息被添加到系統中安排在這些更新,例如通過使用觸發器。

所以底線,除非遇到性能問題,否則保持表格正常化,就像它們一樣。當你預計有數百萬條消息和回覆時,一些反規範化可以幫助加快速度。索引表可以幫助離線創建彙總統計信息,除非您需要它們是準確和最新的。

+0

嗯, 對總統計表格有趣的想法。 將不得不考慮這一點。 系統沒有對消息進行任何操作,所以這很好。 你基本上已經把我的問題放在一行中,我選擇規範化還是性能,表格本身可以變得非常大,因爲一條父信息將有大約15k條子信息,那麼你的建議是什麼? – Hailwood 2011-01-19 00:55:02

0

你可能會更好過工作它在這兩種情況下,但我會重寫查詢

SELECT 
    p.* 
    count(child.*) childCount 
FROM 
    parent_message p 
    LEFT JOIN child_message c 
    on c.parent_id = p.parent_id 

SELECT DISTINCT 
     rm.* 
    FROM 
     reply_message rm 
     INNER JOIN child_message cm 
     rm.child_id = cm.id 
    WHERE 
     parent_id = '66' 

我也將列出字段而不是執行SELECT *

+0

三江源對於這一點,我甚至沒有想到加入他們正確,至於選擇*,那更縮短了查詢,我不實際使用:) – Hailwood 2011-01-19 00:52:28