审计系统的一剂良方——事件溯源

大多数系统在数据库存的都是系统的状态数据,好比一个用户表可能会存用户的姓名、头像、个性签名等信息。若是只存状态数据的传统模式会有什么问题呢?sql

问题起源

假设你公司作了一个系统,并正式上线了。通过一周的推广,老板问你要一些用户的行为数据。老板想知道全部用户平均修改个性签名的次数。数据库

对于传统的数据库设计,当用户修改个性签名,会执行相似以下的 SQL 语句:设计模式

UPDATE Users SET Sign='Talk is cheap, show me the code.' WHERE Id=123

问题是目前数据库没有记录用户修改密码次数的字段。因而,为了更快的实现老板的需求,你须要给数据库的用户表增长这样一个字段。用户每次修改个性签名的时候,这个字段值加一。数据库设计

这样虽然很好的解决了问题,但若是这种需求愈来愈多,好比老板又问你要全部用户平均修改密码的次数,就会有一些明显的问题:学习

  • 应对这种需求须要修改代码,从新测试和发布。
  • 须要修改数据库,会使得数据库设计愈来愈复杂。
  • 增长的字段依然是状态数据,没法反映某时间段用户的行为。好比没法获取某用户上次修改密码的时间、每一年修改了多少次密码等信息。

上面用户的个性签名、密码修改次数的例子算是简单的需求,增长字段、修改代码还能够应付。但需求稍微变换一下,复杂一点,好比要分析某商品在用户购物车中变化的状况,如什么时间点添加这个商品到购物车的用户最多、当用户从购物车移除该商品的同时购物车中有哪些竞品等。这种需求带来的修改,会使数据库设计和系统变得无比复杂,产生的工做量也是巨大的。测试

可见,随着系统不断扩大,业务需求愈来愈多样化,这种数据库存储状态数据的传统模式就会愈加捉襟见肘了。设计

面对这种“痛”,事件溯源多是一剂良方。日志

一剂良方

事件溯源(ES,Event Sourcing),字面上理解就是使任何对数据的修改均可追溯。code

事件溯源是一种设计模式。相对于传统的在数据库中存储系统的状态,事件溯源在数据库中存储的是系统发生的事件。blog

举个例子,当用户在系统中注册后,一个UserCreated的事件就被存储了。而后,当用户修改了密码,一个UserChangedPassword的事件就被存储了。对于这个用户而言,经过事件溯源设计模式,系统能够知道该用户的一举一动。好比按照时间线,某个用户的事件多是这样的:

这样对于前文用户平均修改个性签名次数的需求,就能够轻松应对了。只须要查询事件为UserChangedPassword的数量再除以用户总数便可。

事件溯源在现实世界中更接近人们的思惟习惯,好比当有人问你今天过得怎么样时,你不会告诉他们今天你的体重是多少、吃了几顿饭(状态数据),而会告诉他们发生了什么有趣的事情(事件)。因此对系统来讲,也更容易建模。

适用范围

事件溯源适用于数据分析,能够生成各类维度的报表,帮助你更深刻地了解数据;能够提供审计日志,帮助你准确地知道系统是如何从一个状态变成另外一个状态的。好比你在银行存了一千万,隔了一年后发现帐户余额只有一百块。事件溯源就能够告诉你,你是如何一步一步从一个千万富翁变成穷光蛋的。

听上去不错,但事件溯源也不是包治百病的万能药。

事件溯源会给系统增长额外的复杂性。每每用传统方式能够简单快速完成的增、删、改功能,使用事件溯源就会多绕几步。它一般须要与 CQRS (Command Query Responsibility Segregation,命令查询职责分离) 结合使用,这对开发人员而言,学习成本更高。

若是是不须要审计日志的小规模系统,使用事件溯源就会得不偿失。若是团队中没有在这方面有足够的经验的开发者,也不要轻易在生产环境中使用它。没有精钢钻,不揽瓷器活。

相关文章
相关标签/搜索