Design patterns 设计模式适用于许多实体历史?

Design patterns 设计模式适用于许多实体历史?,design-patterns,Design Patterns,我的应用程序中有一些实体类。我想将对此实体的所有更改和一些发生的事件保存在历史记录表中。问题是实体类是不同的,用不同的原语构建,它们之间的关系也不同 例如,在购物应用程序中可以有:用户、商品、交易、手表。我希望能够像这样向用户显示一些活动日志: 16:00你在2468号交易中买了《魔戒》 15:30你把“霍比特人”加入了你的观察名单 15:00被观看物品的“Silmarillion”价格从15欧元降至12.50欧元 14:30你把名字从“托马斯兹”改成了“汤姆” 此日志中涉及许多内容: 带

我的应用程序中有一些实体类。我想将对此实体的所有更改和一些发生的事件保存在历史记录表中。问题是实体类是不同的,用不同的原语构建,它们之间的关系也不同

例如,在购物应用程序中可以有:用户、商品、交易、手表。我希望能够像这样向用户显示一些活动日志:

  • 16:00你在2468号交易中买了《魔戒》
  • 15:30你把“霍比特人”加入了你的观察名单
  • 15:00被观看物品的“Silmarillion”价格从15欧元降至12.50欧元
  • 14:30你把名字从“托马斯兹”改成了“汤姆”
此日志中涉及许多内容:

  • 带有项目“LotR”的新交易实体2468
  • 新的手表实体与“霍比特人”和我的帐户相关联
  • 更新的项目价格(但存储旧价格和新价格)
  • 更新的用户名(旧的和新的已存储)
我的主要问题是如何跟踪这些数据

  • 我应该拥有和实体表一样多的表来保留它们的更改吗?用户版本、项目版本等
  • 我是否应该查询所有版本表、联接和排序结果以生成此日志
  • 或者应该有一个表版本,其中包含列“Entity”、“OldValue”、“NewValue”-那么约束和外键呢?这不是太脏了吗
  • 这个有设计模式吗
  • 最后,如果你知道——Facebook是如何做到这一点的?:)
    也许您可以使用Drupal和其他一些CMS采取的一种方法,即将相同数据的当前版本和旧版本保存在一个表中。此处更详细地描述了示例:

    我真的不知道这个模式的名字是什么,但我相信它自己赢得了一个


    这具有明显的速度优势。为了跟踪引入这些更改的操作,您可以使用一个单独的表,其中可能包含一些指向更改前后记录的链接。

    您可以使用commandpattern。如果您将它们添加到堆栈中,您就有了历史记录

    每个命令都具有执行其任务所需的所有信息。 这意味着每个命令都是不连续的,很难为特定的用户视图存储和查询它们(因为用户需要查看其他人调用的命令中的信息(例如15:00关注项目的“Silmarillion”价格从15欧元降至12.50欧元)

    您可以在数据库中按如下方式表示命令:

    Command
    -------
    id
    name
    timestamp
    user
    
    CommandParameters
    -----------------
    commandId
    name
    value
    
    现在,您可以构建一个查询,显示用户的所有相关命令或用户在其监视列表中的特定项(您可以添加一个包含与用户和项相关的所有命令的表)

    其中,对于用户,您可以获得最终用户可以执行的所有命令;对于项目,您可以获得与项目相关的所有命令,如价格更新、库存变化等

    现在,您可以提供适配器,通过这些命令生成更用户友好的消息。通过这种方式,您可以在其他上下文中使用相同的命令,并在其上安装另一个适配器


    我希望这能让您更进一步。

    您可能对名为的设计模式感兴趣

    事件源确保对应用程序状态的所有更改 存储为事件序列。我们不仅可以查询这些事件,还可以 还可以使用事件日志重建过去的状态,并作为 自动调节状态以适应追溯 变化

    至于如何存储这样的事件,实际上取决于需求。有时只需将其序列化为JSON就足够了


    事件源包含在CQR的大多数实现中,因此您可以在几乎任何与之相关的资源中找到附加信息。

    一般来说,这是正确的,这是我的第三个主张。但是很难将外键保留到不同的实体。您是否成功地在类似的上下文中实现了命令模式?命令模式非常适合我请分享您对JSON和CommandParameters的想法。谢谢您的更新!我不得不用旧版本污染我所有的每个表-用户、项目、事务、手表等。这并不能解决我如何像示例一样向用户显示一个好日志的问题。谢谢您,我认为您的答案到现在为止是最完整的,它链接到了许多相关的源,并提供了进一步的信息解释。
    HistoryBuilder
    --------------
    viewName
    commandName
    filterField