你如何設計模式來跟踪 NoSQL 中的更改歷史?
我正在考慮為需要跟踪更改的項目嘗試文件儲存數據庫。我想使用 firebase 進行原型設計,但我認為 MongoDb 中的架構/實現是相同的
(簡化的)設置是我有三個表/集合
Project
,Asset
和User
. A(已登錄)User
可以更改(創建、更新或刪除)aProject
或Asset
.Asset
可以分配給(最多一個)Project
。任何時候
Asset
或Project
進行任何更改,我都想擷取User
進行更改的,何時進行更改,並且在大多數情況下,是以前的狀態。
向項目和資產文件添加三個屬性-
WrittenWhen
和. 將這些填充到“真實”數據中。WrittenBy``IsActive
當記錄更改時複製它但 IsActive 標誌翻轉。
WrittenWhen
保留和的原始值WrittenBy
。原始記錄使用修改使用者的 id 和時間戳進行更新。我這樣做是為了讓任何其他持有該記錄的魔術 id 的記錄都保留該指針。僅在讀取時查找具有正確值 IsActive 的記錄。
如果歸檔記錄被寫入單獨的集合/命名空間/數據庫/您的技術支持的任何內容,則可以省略 IsActive。
謝謝邁克爾,我對這個實現有幾個擔憂;大小 - 這可能有很多冗餘數據,可能會儲存超過所需數據的 100 倍或更多倍的數據,對於許多使用 mongodb 的部署,這可能不是問題,但是對於像 firebase 這樣的 BaaS,這可以很大的區別。我的另一個擔心是它不知道編輯了哪個數據點,除非您與以前的不同,並且可能有多個使用者編輯多個數據點,以顯示“最後更新由*** on *** ”它可能需要查找許多較早的記錄 – 丹尼爾 3 月 10 日 16:16
您提出的積分是有效的。另一種設計是僅將更改的值儲存在歷史儲存中。然後會有一條記錄(主鍵欄位,更改欄位的名稱,舊值,新值,寫入者,寫入時間)。僅儲存更改的部分會直接導致兩個新問題。
第一,您必須為每次寫入分離更改的部分,而不是將差異成本推遲到需要時。通常,我們希望 OLTP 寫入速度快,並且審計報告對性能不重要。因此,我認為將這項工作推遲到需要報告的時候是合理的。當然,編寫整個記錄的成本將超過編寫較短的僅差異記錄的成本。您可以對基礎架構進行基準測試,看看這是否重要。
第二,通過僅儲存增量,您會失去發生更改的數據上下文。我的意思是只儲存增量,我們可以讀取單個審計記錄,例如,欄位 53 從“A”更改為“B”。發生這種變化時,所有其他欄位的值是多少?要找出答案,您必須回顧歷史,直到找到您感興趣的其他欄位的最新值,可能一直到“實時”記錄。同樣,我不知道這是否是您的場景的有效案例,或者更改頻率和審核讀取頻率是否會使其成為問題,但這是值得考慮的事情。
使用任一方案顯示“最後一次更新…在…上”是對最後寫入的歷史記錄的單個記錄查找,因為這兩種方式都將此資訊儲存在每個歷史記錄上。要查找儲存的完整記錄發生的變化,需要第二次讀取和差異,而增量儲存不需要。重建歷史記錄將是完整記錄的輕鬆工作和增量處理的繁重工作。
我不太了解您的要求或約束,無法全面評估一種設計。由於易於實施和(可能的)性能,我更喜歡我記錄的那個。但是,我要指出,沒有免費的午餐。這項工作必須在某個地方、某個時間完成。