我想在项目中应用CQRS模式,但我不明白如何加入和反规范化数据。
考虑一个数据模型,其中有 2 个实体:多对多关系中的 Product 和 Store 以及名为 stock 的属性(特定商店中的产品数量)作为关系属性。
还请考虑一下我已经创建了 2 个微服务:
- ProductService:负责处理产品的CUD操作;
- StoreService:负责处理存储上的 CUD 操作。实体 ProductStore 由该服务管理。
此时,我想创建第三个微服务,负责连接 ProductService 和 StoreService 的数据,以检索所有可用的产品。在这里,CQRS 模式似乎是最好的解决方案:我将创建一个物化 View ,并使用其他 2 个微服务发布的域事件来同步它。太棒了!
现在是疑问。
假设物化 View 有以下列:
产品 SKU、产品名称、库存、商店名称、商店地址。
当我更新Product实体或Store实体时,同步 View 没有问题,因为我已经有数据了。但是当我收到 ProductCreated 事件时该怎么办?此事件仅包含有关产品的信息,没有其他信息,因此 stock、store_name、store_address 将为 NULL。如何在我的 View 中保存此事件?我是否应该将不完整的数据保存在其他地方并在收到完整数据时更新我的 View ?
谢谢!
最佳答案
CQRS、事件源和物化 View
你是对的,一般来说,CQRS、物化 View 都与事件溯源模式相匹配。这意味着我们不断将事件添加到事件存储中(这是单点事实)。我们通过调度从事件存储读取数据并创建/更新物化 View 的作业来生成物化 View ,或者我们可以通过事件触发器生成物化 View 。因此,当您获得商店服务事件(可能是在产品事件之后)时,您知道这是特定交易的最后一个事件,并且查询事件存储来更新物化 View ,并且您将拥有所有数据。简而言之,继续在事件存储中转储并立即查询事件存储以更新您的物化 View 。添加事件源本身可能很复杂,因此如果您可以在没有事件源的情况下进行管理,请不要过于复杂。
您的案例
如果您没有使用事件存储,那么在您的情况下,您可以将部分/不完整的信息保存在物化 View 中,并在其他正在进行的事件到达时不断更新它。您将拥有单个引用/ key ,您将根据该引用/ key 在物化 View 中更新数据。由于整个系统最终是一致的,您将必须管理如何在前端显示不完整(如果必须)的数据,或者如果您不想显示,则可以标记它(当最后一个事件到达并且信息是时取消标记)完成)。
关于将来自不同微服务的数据连接到 CQRS 模式中,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57328269/