2011-03-17 120 views
7

給定一個像StackOverflow這樣的網站,創建num_comments列來存儲提交的評論數量,然後在做出評論時更新它,或者只是使用COUNT函數查詢行數,會更好嗎?看起來後者更具可讀性和優雅性,但前者效率更高。 SO認爲什麼?哪個更好的數據庫設計?

+1

如果SO需要連接表以顯示註釋計數,則它不會存在。但是,擔心當你的網站每天被數百萬的綜合瀏覽量擊中時會發生什麼,我們只是說,不成熟 - 所以在你自己的項目中,使用「COUNT」。 – Jon 2011-03-17 21:01:01

+5

不要過早優化。保持數據庫規範化,直到你需要對它們進行非規範化。 – Quentin 2011-03-17 21:02:51

+1

@Jon:有趣......你能詳細說明還是提供鏈接?我在關係模型之外堅果,但總是準備學習... – 2011-03-17 21:03:58

回答

7

絕對要使用COUNT。存儲評論的數量是一個經典的去規範化,會產生令人頭疼的問題。它的檢索效率稍高一些,但是插入的代價要高得多:每個新的註釋不僅需要插入到註釋表中,而且需要在包含註釋計數的行上寫入鎖。

+1

這不是反規範化更多的優化,需要一些觸發器 - 幾乎不是頭疼! – 2011-03-17 22:04:53

+0

@JonBlack - 是的,這是一個優化(儘管如我在答案中所說的那樣,「優化」是否值得不那麼清楚)。同時,它絕對是一種反規範化。特別是,'num_comments'列違反了第三範式,因爲它引入了非關鍵依賴關係 - 一個不依賴於關鍵字的值,但在這種情況下,這些關鍵值最可能來自完全不同的表。至於令人頭痛的問題,這個問題不僅僅是寫出「一些觸發器」,而且隨着數據庫的發展,必須保持觸發器以及其他一切。 – 2017-10-31 01:09:15

3

前者未規範化,但會產生更好的性能(假設讀取次數多於寫入次數)。

後者更規範化,但需要更多的資源,因此性能較差。

哪個更好歸結爲應用需求。

2

我會建議計數評論記錄。雖然其他方法會更快,但它可以提供更清晰的數據庫。添加計數列將是一種數據重複,更不用說額外的代碼步驟和插入。

如果您希望獲得數百萬條評論,那麼您可能需要選擇count列方法。

2

我同意@Oded。這取決於應用程序的要求,也就是如何與現役的網站,但這裏也是我的兩分錢

  • 我會盡量避免將不得不由觸發器進行寫操作,更新以新時評論張貼表被添加。
  • 如果您擔心報告數據,那麼請勿在事務性系統上執行此操作。創建一個報告數據庫並定期更新。
2

「正確的」設計方法是使用另一個表,加入它並COUNT。這與database normalization教導的一致。

規範化的問題是它不能縮放。皮膚只有很多種方法來處理貓,所以如果你每天有數百萬個查詢,而且其中很多涉及到表X,那麼數據庫的性能會低於地面,因爲服務器還必須處理併發寫入,交易等。

要解決這個問題,一般的做法是sharding。分片具有副作用,表中的行不存儲在相同的物理位置,並且主要的後果是您不能再JOIN;你怎麼能JOIN對半桌,並收到有意義的結果?顯然,嘗試JOIN針對表的所有分區併合並結果將比疾病更糟糕。

因此,您會發現,不僅您在實踐中使用的替代方案可以實現高性能,而且還有更激進的步驟可供工程師採用。

當然,除非你有性能問題,分片或甚至去規範化只是讓你的生活更難以沒有實際的好處。

+0

這是如何將標度傾斜到包含num_comments列的? – 2011-03-17 21:37:14