我想建立一个小型事件溯源库。 我在网上阅读了一些教程,到目前为止都理解了。
唯一的问题是,在这些不同的教程中,有两种不同的数据库策略,但没有任何注释说明为什么使用他们选择的方法。
所以,我想问你的意见。 并且重要的是,为什么你喜欢你选择的解决方案。
第一种解决方案是创建每个事件的一个表结构。
第二种解决方案是只创建一个通用表结构,并将事件保存为序列化字符串存储在一个列中。
在这两种情况下,我不确定他们如何处理事件更改,也许他们会创建一个全新的事件。
此致敬礼
我想建立一个小型事件溯源库。 我在网上阅读了一些教程,到目前为止都理解了。
唯一的问题是,在这些不同的教程中,有两种不同的数据库策略,但没有任何注释说明为什么使用他们选择的方法。
所以,我想问你的意见。 并且重要的是,为什么你喜欢你选择的解决方案。
第一种解决方案是创建每个事件的一个表结构。
第二种解决方案是只创建一个通用表结构,并将事件保存为序列化字符串存储在一个列中。
在这两种情况下,我不确定他们如何处理事件更改,也许他们会创建一个全新的事件。
此致敬礼
我自己构建了一个事件溯源库,并选择了选项2,以下是原因。
有人认为可以按每个聚合存储事件,但这取决于项目的要求。
我有一些关于如何使用事件流的文章,您可能会发现有帮助。
解决方案是创建一个通用表的数据库结构,并将事件作为序列化字符串保存到一个列中。
这是迄今为止最好的方法,因为回放事件更简单。关于事件溯源,我的建议是:这是一种很好的模式,但你应该小心,因为并不是每件事情都像看起来那么简单。在我所工作的系统中,我们保存了每个聚合的事件流,但我们仍然有一组规范化的表,因为我们不能接受为了获取对象的最新状态必须运行所有事件(快照有所帮助,但并不是完美的解决方案)。因此,是的,事件溯源是一个好的模式,它为您的实体提供了完整的版本控制和完整的审计日志,它应该只用于此,而不是作为规范化表集的替代品,但这只是我的建议。
public interface IUserCreated : IEventModel
{
}
public class UserCreatedV1 : IUserCreated
{
public string Email { get; set; }
public string Password { get; set; }
}
public class UserCreatedV2 : IUserCreated
{
// Fullname added to user creation. Wrt issue: OA-143
public string Email { get; set; }
public string Password { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
}
public class EventRecord<T> where T : IEventModel
{
public string SessionId { get; set; } // Can be set in emitter.
public string RequestId { get; set; } // Can be set in emitter.
public DateTime CreatedDate { get; set; } // Can be set in emitter.
public string EventName { get; set; } // Extract from class or interface name.
public string EventVersion { get; set; } // Extract from class name
public T EventModel { get; set; } // Can be set in emitter.
}
public interface IEventModel { }
我会选择#2,如果你真的想通过事件类型进行高效搜索,我只需在该列上添加索引即可。
以下是访问涉及此案件主题数据的两种策略。 1)当前状态和2)事件排序。 使用当前状态,我们处理事件,但仅保留主题的最后状态。 使用事件排序,我们保留事件并通过每次需要状态时处理事件来重建当前状态。 事件排序更可靠,因为我们可以跟踪导致当前状态发生的所有事件,但它肯定不高效。保留中间状态(快照)而不仅仅是最后一个状态以避免一直重新处理所有事件是常识。现在我们既有可靠性又有性能。
在加密货币中,有事件排序和本地快照-本地名称是因为区块链是分布式的,数据被复制。