一張大桌子 vs 幾張小桌子
請注意,下面的範例只是一個範例,我的場景要復雜得多,而我嘗試對其建模的方式確實很有意義
假設我正在為我的一個應用程序中的審計事件創建一個表 - 所以所有的“event_created”、“user_created”等等。該表包含幾列,其中一些是其他表的外鍵。隨著時間的推移,這個單一的表可以增長到幾百萬條記錄。
從性能的角度來看,為所有事件使用單個表還是為每種事件使用單獨的表並在單獨的表上操作是否更快、更高效?還是沒有太大區別?為每種事件創建一個單獨的表可能聽起來很傻,但你需要相信我,在我的現實世界場景中,這真的很有意義。
非規範化僅作為最後的手段
不要因為想像中的性能問題而對錶設計進行非規範化。避免陷入過早的優化。
設計合適的結構。生成假數據以填充表。在類似於您的部署方案的情況下執行測試。如果證明存在重大性能問題:
使用 EXPLAIN & ANALYZE 功能研究問題的性質。
- 檢查索引的使用。驗證現有索引是否按預期用於查詢;如果沒有,請使用不同的方法重新編寫您的查詢。在需要的地方添加索引。
研究如何調整 Postgres。
- 學會大小記憶體。
- 了解調整 Postgres 伺服器的其他方法。
- 通過線上影片或幻燈片查看一些會議演講。
- 搜尋官方Postgres 郵件列表。
- 參加Postgres 使用者組會議或Postgres 會議。
- 搜尋 DBA 堆棧交換。
嘗試通過使用諸如PL/pgSQL之類的語言編寫函式來將一些邏輯從您的應用程序移動到數據庫伺服器,其中所有數據都是執行程式碼的本地數據。
在RAID設備上安裝更大的記憶體單元。根據您的情況考慮調整記憶體以分配更多的讀取和寫入;他們通常預設為 50-50。
(順便說一句,請確保您的 RAID 的寫入記憶體有電池供電,以避免破壞您的數據庫或其他文件。)
- 或者,如果使用ZFS而不是 RAID,請學習對其進行調整,以便在更快的驅動器上優先考慮您的數據庫。
考慮使用分區來物理隔離儲存中的行。考慮添加更快的儲存,例如企業級固態儲存,您可以在其中儲存最常用的數據,或儲存您最想快速訪問的數據,例如Big Cheese使用的數據。
- 分區伴隨著限制和權衡。因此,請確保您沒有更好的方法來解決性能問題。
- 如果您確實使用分區,請注意最近版本的 Postgres(我模糊記得是 10、11、12)已通過聲明性分區的改進而得到顯著改進。
聘請 Postgres 專家為您的測試和調整提供諮詢。
只有在用盡所有方法來解決已證明的性能問題之後,您才應該考慮非規範化。
Postgres 是一個強大的企業級數據庫系統。現代硬體上的幾百萬行具有足夠的 RAM 和明智的索引應該完全沒有問題。
另一方面,如果您的不同類型的事件代表不同的實體,那麼它們應該保存在單獨的表中。我們如何知道相似類型的行是否是不同的實體?可能會在詢問中找到線索:它們是否具有具有相同語義的大部分相同的列?您的使用者是否想要一起顯示或報告?您可能想要聚合(計算計數、平均值、中位數等)在一起嗎?
請注意,作為一個歷史悠久的產品,可以追溯到電腦硬體在功能和配置方面比今天的硬體更受限制的日子, Postgres 預設情況下在初始安裝時**具有相當保守的設置。**例如,預設情況下 Postgres 在較舊的Raspberry Pi上執行!因此,任何在功能更強大的硬體上執行更大數據庫的人都應該進行一些調整。