MongoDB版本控管設計模式

Han
阿Han的圖文解字筆記
Dec 11, 2020

MongoDB非常擅長查詢大量的數據並經常更新這些資訊, 在多數的情況之下, 我們只要查詢資訊最新的狀態, 那假設我們需要查詢資料的上一個狀態呢? 如果我們需要一些文檔版本控管功能時怎麼辦呢? 這就是我們可以使用版本控管設計模式的地方了。

概念

這個模式之下會保存文檔的歷史版本, 我們就不用導入另外一個版控系統, 怎麼做呢?

  1. 首先我們要在需要版控的document加上一個欄位version, 用以追蹤這個document是哪一個版本。
  2. 會有兩個Collection, 一個是最新的資料, 也是最常用來查詢的地方, 另一個則會存放資料的修訂版。

什麼情況下適合使用這種模式?

  • 每個Document不會有太多的修訂版。
  • 不會有太多的Document要做修訂版的功能。
  • 大多數的查詢都是針對最新版本。

案例

以雲端服務Google Sheet來說, 提供使用者開啟版本記錄的功能, 每次的異動事件都會產生一筆記錄, 而這個記錄會告訴我們更動了哪些部份, 此外也提供「還原這個版本」的功能。

圖片來源

雖然我們不知道Google背後是怎麼做到這些功能的, 但以MongoDB來說我們可以用一些Pattern來實現, 這個Pattern就是The Document Versioning Pattern, 首先我們會有三個Collection如下:

  • documents: 這裡只會存放最新版本的Document, 並以version欄位來記載當前的版本, 通常搜尋會直接對這個Collection進行搜尋, 如果需要依照版本號去追朔, 則可以轉向document_revisions去搜尋。
  • document_revisions: 這裡會存放Document的修訂版本, 內容與documents一樣, 差別只是會有多份, 並以版本號作為區隔。
  • log: 這裡只會存放異動的事件, 這樣我們依照時間就能知道前後異動內容跟當時的版本號。

策略一: 歷史記錄

圖片來源
  • 修改/刪除前都先將上一個版本的document丟到修訂版本區。
  • 如此一來新增時就不用做任何動作了。
  • 優點: 空間節省, 修訂版本只會保留最新版以前的版本。
  • 缺點: 假設今天要指定某個版本去做搜尋, 那麼勢必得二次搜尋,先找找最新版本區有沒有存在, 再轉往修訂版本區找尋。

假如我們的應用是常常查詢出最新版, 而且我們對於版本號的搜尋上可以明確的識別出最新版本與歷史版本, 那就很適合採取歷史模式, 以「異動事件回朔版本」來說, 我們可以列出異動的Log給User去觀察每一次的異動內容及當時的版本, 那麼將這些異動事件由小到大排序後, 是不是就能將最前面的那筆記錄視為最新版本, 而後面的幾筆異動記錄都視為歷史版本, 這樣一來當User點擊到歷史版本的異動記錄並且要按下「還原這個版本」的時候就能知道要往歷史區找指定的版本來還原。

策略二: 快照方式

圖片來源
  • 新增/修改後都快照一份到document_revisions
  • 如此一來刪除就不用再快照一次了, 因為最新版本區也不存在該筆, 因此版本號也不會在遞增, 回朔時修訂版本區就已經有最新版本了。
  • 優點:
  • 實做簡單, 每次更新完最新版就把最新版的內容原封不動的寫到修訂版本區。
  • 對某個版本進行查詢時較便利, 直接從修訂版本區找就可以了。
  • 缺點: 最新版本區與修訂版本區會同時存在一份最新版, 造成空間的浪費。

假如我們的應用是不能很明確的知道當時的版本是最新的還是歷史的狀況下, 那麼就很適合將最新版及歷史版本都存起來, 如此一來會減少兩邊查詢的狀況, 而這種應用可能也比較特殊一些, 例如: 背景服務在執行時產出的結果在當下是標示最新版本v3沒錯, 但是一旦我們修改了設定, 版本變為v4了, 此時我們也很難知道產出的結果是用哪個版本所產生的, 若是採用歷史區的策略, 只能先找找看最新版有沒有該配置, 再轉往歷史區找。

--

--