對涉及大量插入的項目的數據庫/儲存引擎建議?
我正在研究一個每天涉及大量插入的項目。我將有一個使用者列表(例如使用者集 500k ),為此我需要每天監控與他們相關的某些活動。
例如,假設有一組 100 個使用者說 U1,U2,…,U100
我需要將他們的每日分數插入我的數據庫。
考慮使用者 U1 在 6 月 30 日 - 7 月 6 日期間獲得的總分,如下所示
June 30 - 99 July 1 - 100 July 2 - 102 July 3 - 102 July 4 - 105 July 5 - 105 July 6 - 107
數據庫應該保留每個使用者的每日分數,比如
對於使用者 U1,
July 1- 1pt (100-99) July 2- 2pt (102-100) July 3- 0pt (102-102) July 4- 3pt (105-102) July 5- 0pt (105-105) July 6- 2pt (107-105)
同樣,數據庫應該保存全套使用者的每日詳細資訊。
在稍後階段,我設想從這些數據中提取匯總報告,例如每天、每週、每月的總得分等;並將其與舊數據進行比較。
我需要從頭開始。我對 PHP 作為伺服器端腳本和 MYSQL 有經驗。我在數據庫方面感到困惑?由於我每天需要處理大約一百萬次插入,所以應該注意什麼?
MySQL 是否符合我的要求,如果可以,應該使用什麼儲存引擎?最初,我設想創建一個帶有外鍵使用者 ID 的使用者表和以日期為欄位的月度得分錶。後來我得到建議,先將內容寫入 csv/excel,然後在特定時間段後將它們載入到表中。
文件插入是否在這方面更有利。
還是我應該嘗試其他一些數據庫,NoSQL 方法?
編輯
我正在總結我的要求,我需要一個包含一百萬使用者的數據庫,其積分每天都會作為單獨的條目進行更新。這將定期進行,以便每個使用顯示每日點的每天都有一個欄位,可以每週/每月/每年匯總。我對數據庫設計以及部署後可能發生的問題感到困惑。每天一百萬或更多的數據庫操作。在這種情況下要考慮伺服器和其他事情。
任何幫助將不勝感激。在此先感謝。
讓我們把這個問題分成幾個部分。
問:我需要每天插入 1mm 行。很多嗎?
並不真地。1 毫米除以 24 小時除以 60 分鐘除以 60 秒,您每秒可以插入大約 12 次。從粗略的角度來看,在沒有調整的典型商用伺服器中,每秒 1,000 次插入並不罕見。
誠然,您的負載不會像那樣完美地平均化——你會有負載的爆發——但我不會根據每秒少於 10k-20k 的插入來做出數據庫平台決策。那裡的任何平台都可以很好地工作。
問:我應該如何建構數據?
縮小 - 不要想表,想數據庫。如果您要永久保留這些數據,並且它是真正只插入且沒有更新的,那麼您可能希望為時間長度啟動一個新數據庫。您的插入可能只進入一個數據庫中的一個表,但每年都會創建一個新數據庫 (MyApp_2015) 並將 2014 年的舊數據密封為只讀。您可以停止備份它(只要您仍然有一次良好的備份),停止進行索引維護,統計更新等。
PHP 只需要知道插入的目前數據庫,使您的設計更容易。只要您知道將涉及多個數據庫,歸檔過程就會在很久以後成為 DBA 任務。
如果您每秒持續執行超過 1,000 次插入,並且想要更輕鬆的性能管理,那麼我還建議將分片建構到初始設計中,而不管數據庫平台如何。不要誤解我的意思,任何現代數據庫每秒都可以處理超過 1,000 次插入,但是現在設計分片只會在以後為您提供更大的靈活性。每秒插入 12 次,這不值得設計/測試麻煩。
問:我應該如何做報告?
在理想情況下,不會針對實時伺服器進行報告。針對數據庫的恢復或複制副本執行報告。這有兩件事:它減少了實時伺服器的負載,它驗證您的備份,確保您在其他地方獲得了寶貴的數據。
如果它是您正在查看的數據倉庫系統,您可能希望考慮InfiniDB。它是一個為 DW 類型載入而設計的開源列式儲存引擎——它屬於Michael Stonebraker 定義的NewSQL範式。還有InfoBright,這是一個類似的產品。關於 InfiniDB 的注意事項 - 它現在在 MariaDB.org/com 的支持下 - 不確定該項目將來會走向何方。
當然,你可能根本不需要任何特殊的軟體——一台好的伺服器上的普通 MySQL 可能就在你的小巷裡。正如已經指出的那樣,11 次操作/秒在現代(即使是相對適中的)伺服器上並不是很多。
顯然,這取決於您的特定查詢/應用程序、負載和 c。當然,還有預算:-)。我會敦促您在採用任何給定方法之前評估解決方案並進行測試。
$$ EDIT $$ 我在想我只考慮了 MySQL 相關的解決方案。看看這裡(功能比較)關於大型供應商的免費贈品伺服器中可用的內容。還有 PostgreSQL,在許多人(尤其是我)的眼中,它是一個比 MySQL 更強大的數據庫伺服器。
$$ EDIT - in response to comments $$ 這裡沒有太多的學習曲線——NewSQL 背後的關鍵思想之一是它顯式地保留了 OldSQL 的大部分內容,例如 SQL 語言和 ACID 事務。基本點是 NewSQL 將數據處理分為兩種類型的任務,並為每種類型採用不同的方法。
OLTP
(線上交易處理 - 銀行、購物等)是在一個共享的無分片記憶體架構上完成的,OLAP
(線上分析處理 - 你的問題 - 數據倉庫/DW - 即長期報告/聚合)是通過壓縮的列式儲存完成的數據的。關於速度問題——對於數據處理量很少的簡單的重讀應用程序來說,MySQL 可能更快(而不是快很多),但是一旦你開始編寫複雜的 DW 類型的查詢,PostgreSQL 就會開始大放異彩!
看看這里和這裡。如果您正在查看比較,請不要注意任何提到 MyISAM 表類型的站點 - MySQL 現在的預設值是 InnoDB,它確實強制執行 ACID 事務和引用完整性。
$$ EDIT - in response to OP’s further comment about having no knowledge of PostgreSQL $$ 對於 MySQL 和 PostgreSQL,SQL 的基礎基本相同。去年之前我從未使用過 PostgreSQL(我是一名成熟的學生),不得不在大學機器上安裝 PostgreSQL 實例。它從原始碼編譯而來,開箱即用。從本質上講,數據庫伺服器的基本原理相當相似(但並不完全相同!)。
然而,值得注意的是,PostgreSQL a) 比 MySQL 更符合標準,b) 它的 SQL 語言更加豐富。檢查約束在 PostgreSQL 中有效——它們在 MySQL 中無效(我仍然覺得這是一個令人震驚的缺陷!)。更糟糕的是,如果將它們包含在 CREATE TABLE 語句中,伺服器將接受它們而不會引發錯誤!
PostgreSQL 有視窗函式和公用表表達式 (CTE) - MySQL 沒有(至少不是主流 - InfiniDB 有)。如果您想要一個快速、重讀的 OLTP 數據庫,我會選擇 MySQL。如果你想要一個嚴肅的 DW 數據庫並且你從一開始就可以選擇,我會選擇 PostgreSQL。
恕我直言,從長遠來看,您不必在自己的程式碼中實現 CTE 和視窗函式,從而為自己節省大量工作。看看施瓦茨男爵在這里和這裡寫了什麼。施瓦茨寫了 關於 MySQL 高性能的書。