2011-08-23 111 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的想法。感谢您的更新! –