簡體   English   中英

大型數據集的數據庫設計

[英]Database Design for large datasets

我目前正在設計一個數據庫表,其中我們將有幾億條記錄,我想知道管理它的最佳方式是什么。 對於這些類型的數據集,我們最終會遇到維護問題,例如表還原或更改表需要很長時間。 現在我對如何處理這個問題有了一些想法,但也許有更好的方法?

由於我們的數據越新就越相關,我們可以將其拆分為短時間范圍(例如過去 30 天)和舊數據集(比過去 30 天舊)。 為此,我看到了兩種可能性:

將其拆分為兩個分區,當前分區和舊數據分區

好處:

  • 當前數據分區的表恢復會很快,因為它不是那么大。 在緊急情況下,我們會先恢復它,然后僅使用該數據重新啟動系統。 這對於用戶來說是可以接受的場景
  • 我們可以正常讀取/寫入表 - 所以不需要特定的應用程序邏輯

缺點:

  • 遷移腳本(更改表,我們可以在線使用,但如果我做對了,它不適用於每個用例)需要很長時間,因為它們仍然針對兩個分區運行。 對此的解決方案是讓舊數據分區為用戶脫機並在后台運行。 因此,在此期間用戶將無法訪問舊數據,但這沒關系。 這樣的事情可能嗎?

手動將其拆分為兩個表並通過夜間作業移動數據。 在上面我們放了一個視圖來選擇數據

好處:

  • 我們可以通過不再將舊數據表包含在視圖中並運行alter table 腳本來使舊數據表脫機。 完成后,將其放回視圖中。 由於用戶不會再找到數據,他也將無法修改它
  • 表恢復會很快,因為我們會先恢復當前表,更新視圖並讓用戶再次使用它。 舊數據表的恢復需要一段時間,但沒關系

缺點:

  • 既然是視圖,我們只能通過它進行選擇。 如果涉及修改數據,我們需要為兩個表編寫更新查詢,因為用戶想要更新舊數據。 所以從應用程序的角度來看,它需要自定義邏輯

所以我的問題是,在這種情況下,最佳實踐是什么? 你會建議做什么?

謝謝

幾億是很多,但對於今天來說並不是一個大數據集 大型數據集有數十億條記錄。 這里的問題是我認為,您的數據增長速度有多快? 你對它運行什么類型的查詢? 如果您的數據增長非常緩慢,那么即使沒有分區,任何數據庫軟件都可以足夠快地處理該數量。 如果它增長很快,最好進行一些分區。

如果您有 OLTP 工作負載,那么小的查詢具有高延遲但數量很多,最好將熱數據保存在單獨的位置。 如果它們取決於時間,我建議您使用基於日期時間列的本地分區,按年份分區。 這樣,大多數基於最近數據的查詢只會檢查最新的分區,並且可能只檢查整個數據集的很小一部分。

如果最近意味着很短的時間,比如 1 個月,那么上述方法雖然仍然有用,但還是不夠。 因此,您可以在其上創建另一個熱數據表 現在您有一個按年份分區的大數據表(始終包含所有數據)和一個包含最近數據的小表。 為了克服缺點,你可以這樣做:

  • 更新/插入/刪除
  • 所有查詢都轉到主表; 如有必要,每個操作的觸發器將復制對熱數據表的操作。 (數據庫級邏輯)
  • 或者您可以將相關查詢發送到兩個表並確保它們在應用程序級別(應用程序級別邏輯)上保持一致。 這個可能會更高效,因為 mysql 觸發器可以更多地減慢數據庫的速度。

  • SELECT 查詢將根據查詢轉到新表,否則轉到主表(按年份分區有助於提高性能)。 如果您想要靈活,也可以使用代理來完成查詢拆分。 Proxysql可以輕松處理。 它還有其他好處,例如緩存和連接多路復用。

  • 要丟棄熱數據表中的舊數據,您可以每天執行一個事件以刪除超過 1 個月的記錄。 如果您有成千上萬的要刪除,則應將它們分成較小的塊刪除,以防止出現鎖定、滯后和大量資源消耗等問題。 另一種方法是使用is_deleted列來識別過時的記錄,並以此進行分區。 隨時刪除分區是即時的。

對於非阻塞 DDL 操作,有一些開源工具可以在線遷移您的架構,而不會降低很多性能。 查看pt-schema-changeghost

(專注於舊數據與新數據)

如果表按時間順序排序並且您主要訪問“新”數據,那么大量緩存和它提供的性能將自動內置。

只要確保使用 InnoDB 並讓PRIMARY KEYAUTO_INCREMENT (或以DATETIME開頭)。

讓我們運行一些數字。 如果表中有 300M 行,每行占用 100 個字節(一個簡單的經驗法則),那么表的數據占用 30GB。 索引和其他表會有更多。 如果您在具有 64GB RAM 的服務器上運行(今天並非不合理),那么所有內容都可能適合 RAM 並且不需要太多 I/O。

相反,如果您只有 8GB 的​​ RAM 並且大部分活動都在表的最新 10% 中,那么同樣,它將被很好地緩存。

(注意:I/O 是性能的最大硬件組件。)

通常會阻礙大型表設計的是索引、查詢公式,甚至是整體架構。 但是,由於您沒有關於此類的詳細信息,因此我跳過了該內容。

您提到了一種粗略的手動分區表的方法。 有一些內置的東西: PARTITIONing 但它不太可能幫助插入、更新或選擇,所以我不推薦它而不做進一步討論。

如果您最終會清除“舊”數據(比如一年后),那么PARTITIONing一個好主意。 如果表只保存 1 年的數據,我將使用每周分區。 如果您需要,我們可以進一步討論。 請注意,唯一的好處是通過DROP PARTITION刪除舊數據; 分區是。

SUBPARTITIONs沒有任何幫助。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM