什麼架構最適合在 MySQL 中儲存大型 3 維數組?
我希望在 MySQL 中創建一個大型 3 維數據庫。該結構基本上是一個標準的 MySQL 表,添加了時間組件/維度。請參見以下類比:
{ x, y, z } = { 列、行、時間 }
z維度將是時間,我想盡可能多地儲存。我們希望以適度的性能儲存大約 1TB 的總儲存數據。換句話說,我們希望每 30 秒拍攝一個 MySQL 表的快照,持續多年。每次都是同一張表,大約有 10 列 {x} x 1000 行 {y}(大約 50KB)。因此,如果您願意,我們希望每 30 秒對 50KB 表進行一次快照。
所以這會產生以下問題:避免需要儲存無窮無盡的表。我在 Stack Exchange 上的各種文章中讀到,在數據庫中擁有數百萬個表是一種糟糕的架構,並且這樣的設計性能會受到影響。所以這是我能想到的兩種可能的架構:
- 創建一個新表並使用 epoch 時間命名,並無休止地創建數百萬個新表(不好)。
- 創建一個包含兩列的數據庫:epoch_time 和 json。對於原始表的每個快照,每 30 秒將其轉換為 json 字元串並將整個表儲存在 json 列中。所以基本上,一個包含數百萬行包含 json 序列化表的數據庫。
2 號是最好的架構嗎?有沒有更好的方法我可能會失踪?
三角洲
您正在“快照”的數據——它多久更改一次?
我建議考慮只儲存“增量”。當快照的某些部分根本沒有改變時,增量是空的,你什麼也不能儲存。
為了在過去的某個時間重建快照,處理成本很高——您需要遍歷版本,隨時應用增量。
執行增量有兩種方法——向前或向後。前進,您將從原始(完整)快照開始,然後應用增量直到所需時間。“向後”具有最新快照完整的優勢。向後“減去”變化。
既然您說“多年”,那麼每天拍攝完整的快照可能是明智之舉。然後查找特定的 30 秒秒快照不會涉及超過 2880 個增量。這顯然會導致速度/空間折衷——完整快照很龐大,但不頻繁的快照會導致“重建”時間過長。
扳機
與其使用“快照”,不如使用 a
TRIGGER
來建構“審計跟踪”。這類似於我提到的“增量”,但更好的是它是連續的,而不是“每 30 秒”。我記得的案例在審計跟踪中有超過 10 億行;每行(大約)都有時間戳、表名PRIMARY KEY
和該行所有列的壓縮 JSON blob。某些變體可能會更好地滿足您的需求。架構
在我看到實際查詢之前,我會建議不要這樣做,
PARTITIONing
因為它通常對性能沒有好處。關於表大小限制的連結缺少一個數字:64TB 是一個非分區 InnoDB 表的限制。
為此,我將描述一種上面沒有提到的方法。它通常用於時間數據。不確定它是否符合您的需求,但它就在這裡。我們的想法是擁有一個帶有兩個附加屬性 begin_time 和 end_time 的原始副本:
create table ... ( ... , begin_time timestamp default now() not null -- MySQL timestamp deviates from standard so perhaps some kind of datetime is better , end_time timestamp -- null means current row )
在載入過程中,將每一行與目前行進行比較,如果沒有任何變化,則將其忽略。如果有什麼改變了目前行的 end_time 設置為 now() 並使用 begin_time now() 插入一個新行。
某個“行”的趨勢很容易,也很容易調查該行在某個時間點的樣子。