使用RDBMS作为事件源存储 [英] Using an RDBMS as event sourcing storage

查看:105
本文介绍了使用RDBMS作为事件源存储的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如果我正在使用RDBMS(例如SQL Server)存储事件源数据,那么该架构将是什么样?

If I were using an RDBMS (e.g. SQL Server) to store event sourcing data, what might the schema look like?

我已经看到抽象中谈到的一些变体

I've seen a few variations talked about in an abstract sense, but nothing concrete.

例如,假设某人拥有一个产品,实体,并且对该产品的更改可以采用以下形式:价格,成本和说明。我对是否愿意感到困惑:

For example, say one has a "Product" entity, and changes to that product could come in the form of: Price, Cost and Description. I'm confused about whether I'd:


  1. 具有 ProductEvent表,具有产品的所有字段,其中每个更改均表示该表中的新记录,以及谁,什么,在哪里,为什么,何时和如何。 (WWWWWH)。更改成本,价格或说明时,会添加一个全新的行来表示产品。

  2. 将产品成本,价格和说明存储在单独的表中,并使用外键将其连接到产品表关系。当对那些属性进行更改时,适当地用WWWWWH写入新行。

  3. 存储WWWWWH,以及代表事件的序列化对象,在 ProductEvent中。表,这意味着事件本身必须在我的应用程序代码中加载,反序列化和重播,以便为给定产品重新构建应用程序状态。

我特别担心上面的选项2。更极端的是,产品表几乎是每个属性一个表,要加载给定产品的应用程序状态,需要从每个产品事件表中加载该产品的所有事件。这个表爆炸对我来说是错的。

Particularly I worry about option 2 above. Taken to the extreme, the product table would be almost one-table-per-property, where to load the Application State for a given product would require loading all events for that product from each product event table. This table-explosion smells wrong to me.

我确定取决于,虽然没有一个正确答案,但我还是想尝试一下什么是可以接受的,什么是完全不可接受的。我也知道NoSQL可以在这里提供帮助,因为事件可以针对聚合根存储,这意味着仅向数据库发出单个请求即可获取事件以从中重建对象,但是我们在数据库上并未使用NoSQL db。

I'm sure "it depends", and while there's no single "correct answer", I'm trying to get a feel for what is acceptable, and what is totally not acceptable. I'm also aware that NoSQL can help here, where events could be stored against an aggregate root, meaning only a single request to the database to get the events to rebuild the object from, but we're not using a NoSQL db at the moment so I'm feeling around for alternatives.

推荐答案

事件存储区不需要了解特定的字段或属性事件。否则,对模型的每次修改都会导致不得不迁移数据库(就像在良好的老式基于状态的持久性中一样)。因此,我完全不建议使用选项1和2。

The event store should not need to know about the specific fields or properties of events. Otherwise every modification of your model would result in having to migrate your database (just as in good old-fashioned state-based persistence). Therefore I wouldn't recommend option 1 and 2 at all.

下面是 Ncqrs 。如您所见,表事件将相关数据存储为CLOB(即JSON或XML)。这对应于您的选项3(因为没有 ProductEvents表,因为您只需要一个通用的 Events表。在Ncqrs中,通过 EventSources表进行到您的聚合根的映射,其中每个EventSource都对应一个实际的汇总根。)

Below is the schema as used in Ncqrs. As you can see, the table "Events" stores the related data as a CLOB (i.e. JSON or XML). This corresponds to your option 3 (Only that there is no "ProductEvents" table because you only need one generic "Events" table. In Ncqrs the mapping to your Aggregate Roots happens through the "EventSources" table, where each EventSource corresponds to an actual Aggregate Root.)

Table Events:
    Id [uniqueidentifier] NOT NULL,
    TimeStamp [datetime] NOT NULL,

    Name [varchar](max) NOT NULL,
    Version [varchar](max) NOT NULL,

    EventSourceId [uniqueidentifier] NOT NULL,
    Sequence [bigint], 

    Data [nvarchar](max) NOT NULL

Table EventSources:
    Id [uniqueidentifier] NOT NULL, 
    Type [nvarchar](255) NOT NULL, 
    Version [int] NOT NULL

乔纳森·奥利弗(Jonathan Oliver)的事件存储实现的SQL持久性机制基本上由一个名为 Commits wi的表组成BLOB字段有效载荷。这与Ncqrs几乎相同,只是它以二进制格式序列化事件的属性(例如,添加了对加密的支持)。

The SQL persistence mechanism of Jonathan Oliver's Event Store implementation consists basically of one table called "Commits" with a BLOB field "Payload". This is pretty much the same as in Ncqrs, only that it serializes the event's properties in binary format (which, for instance, adds encryption support).

Greg Young建议使用类似的方法,例如在格雷格的网站上广泛记录

Greg Young recommends a similar approach, as extensively documented on Greg's website.

他的原型事件表的模式为:

The schema of his prototypical "Events" table reads:

Table Events
    AggregateId [Guid],
    Data [Blob],
    SequenceNumber [Long],
    Version [Int]

这篇关于使用RDBMS作为事件源存储的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆