2011-08-23 226 views
12

我的應用程序中有一些實體類。我想將所有更改保存到歷史記錄表中的這些實體和一些發生的事件。問題是實體類是不同的,建立在不同的原語和不同的關係之間。設計模式適合許多實體歷史?

例如在購物應用程序中可以有:用戶,物品,交易,手錶。我希望能夠表現出一定的活動日誌的用戶是這樣的:

  • 16:00您已經在事務2468購買「指環王」,
  • 15:30您已經添加了「霍比特人「到您的監視列表中,
  • 15:00觀看項目的」Silmarillion「已將價格從15降至12,50歐元,
  • 14:30您已將名稱從」Tomasz「更改爲」Tom「。

有參與此日誌很多東西:

  • 新的交易實體2468與物品「魔戒」,與項目「霍比特人」和我的帳戶鏈接
  • 新觀察實體,
  • 更新的項目價格(但是舊價格和新價格都存儲),
  • 已更新用戶名(包括舊的和新的存儲的)。

我的主要問題是如何跟蹤這些數據?

  1. 我應該擁有許多與許多實體表一樣多的表來保持其更改嗎? UserVersions,ItemVersions等?
  2. 我應該查詢所有版本表,加入並排序結果來生成這個日誌?
  3. 或者也許應該有一個表版本與列「實體」,「OldValue」,「NewValue」 - 約束和外鍵?這不是太骯髒的解決方案嗎?
  4. 是否有這樣的設計模式?
  5. 最後如果你知道 - Facebook如何做到這一點? :)

回答

6

您可能會對設計模式Event Sourcing感興趣。

事件源確保所有對應用程序狀態的更改都是作爲一系列事件存儲的 。我們不僅可以查詢這些事件,我們 也可以使用事件日誌來重建過去的狀態,並作爲一個基礎來自動調整狀態以應對追溯 的變化。

至於如何存儲這樣的事件,它實際上取決於要求。有時只需簡單地將其序列化爲JSON即可。

事件採購包含在CQRS的大多數實現中,因此您可以在幾乎所有與其相關的資源中找到其他信息。

+0

謝謝你,我認爲你的答案現在是最完整的,它鏈接到許多相關的資料來源,並提供進一步的解釋。 –

+0

參見http://cqrsinfo.com/documents/ –

0

也許您可以使用Drupal和其他CMS'es採用的方法,即將同一數據的當前版本和舊版本保存在一張表中。在這裏舉例更詳細的描述:CMS versioning strategies for content

不知道這個模式的名字是什麼,但我相信它爲自己贏得了一個名字。

這具有明顯的速度優勢。在跟蹤引入這些更改的操作方面,您可以使用單獨的表,可能會在更改前後記錄一些鏈接。

+0

我不得不污染每個表與舊版本 - 用戶,項目,交易,手錶等,而且它不能解決我的問題,如何向用戶顯示一個不錯的日誌,如示例。 –

2

您可以使用commandpattern。如果你將它們添加到堆棧中,你就有你的歷史。

每個命令都具有執行其任務所需的所有信息。 這個課程意味着每個命令都是獨立的,對於特定的用戶視圖來說,存儲和查詢它們是非常困難的(因爲用戶需要查看來自其他人調用的命令的信息(比如15:00 Watched項目的「Silmarillion」已經放棄。價格從15到12,50歐元)

可以代表命令在數據庫如下:

Command 
------- 
id 
name 
timestamp 
user 

CommandParameters 
----------------- 
commandId 
name 
value 

現在你可以建立一個查詢,顯示所有相關命令,爲用戶或特定項目用戶在其監視列表中(可以添加包含與用戶和項目相關的所有命令的表格)

HistoryBuilder 
-------------- 
viewName 
commandName 
filterField 

凡用戶你可能最終用戶和項目你會得到相關的如價格更新庫存變動等

項目的所有命令現在可以提供適配器,使執行所有指令這些命令提供更多用戶友好的消息。通過這種方式,您可以在其他上下文中使用與其他適配器相同的命令。

我希望這可以讓你更進一步。

+0

一般來說,這是我的第三個主張。但是很難將外鍵保存到不同的實體。你是否成功實現了類似環境下的命令模式? –

+0

我更新了我的回覆 – Glenner003

+0

命令模式非常適合我喜歡關於JSON和CommandParameters的想法。感謝您的更新! –