【问题标题】:What should be projection primary key on query side - CQRS, Event Sourcing, Microservices查询端的投影主键应该是什么 - CQRS、事件溯源、微服务
【发布时间】:2023-03-10 11:38:01
【问题描述】:

我有一件事让我感到困惑。 我有 2 个微服务。 一个创建命令,另一个使用命令并产生事件(事件存储在 Event Store 中)。

在我的示例中,聚合将 Guid 作为实体 ID,并且在创建聚合时创建 Guid。

让我感到困惑的是,该密钥(在写入端生成)是否应该通过事件传输到查询端(创建命令的微服务)? 或者查询端(投影)应该在读取数据库中有单独的 id。 或者我应该生成一些共享密钥?

这里最好的解决方案是什么?

【问题讨论】:

    标签: microservices domain-driven-design cqrs event-sourcing


    【解决方案1】:

    这是一个奇怪的问题。

    您在投影中的主键实际上可以是任何东西,或者您甚至可能没有。

    这个问题没有“正确答案”......这完全取决于投影。

    如果我的预测只是说与聚合相关的信息变平...例如,我们有一个“订单”,我们为每个订单创建一行,显示有关该订单的摘要信息。在这里使用“OrderId”作为我的主键似乎有些意义。

    如果我的预测是按产品建立订单数怎么办?那么使用“ProductItemId”会更有意义。

    如果在这两种情况下,ID 本身(“OrderId”和“ProductItemId”)可能会发生变化,该怎么办?那么使用另一个键可能会很有意义。

    如果这是一个仅追加的表怎么办?我什至可能不想拥有钥匙。

    同样,没有一个... 正确 ...这里有很多你可能会遇到的情况。

    【讨论】:

      【解决方案2】:

      我认为这完全取决于您的设置。

      如果您正在执行 CQRS,并且您有一个单独的读取服务(在相同的有界上下文中),那么读取端服务可以根据需要对数据进行建模,或者重用或不重用相同的键.

      如果您在两个不同的服务(单独的有界上下文)之间进行通信,那么我建议您在接收服务中创建新的主键并将传入键用作外键。就像处理 SQL 数据库中两个表之间的关系一样。

      【讨论】:

      • 明白,谢谢
      【解决方案3】:

      我认为这取决于您的要求。使用不同的键是否有特定原因?

      鉴于您使用 Guids 作为您的 PK,重用写入方分配的 PK 似乎最简单。

      您可能希望保持密钥一致的一些原因:

      1. 在命令处理期间,向客户端返回了一个 ID,该 ID 可能已经缓存,并且应该合理地期望在查询读取端时能够使用该键。

      2. 如果您的写入端数据是长期存在的,并且您的读取端输出存在错误,如果您的密钥在写入端和读取端保持一致,那么调试出错的地方会容易得多。

      3. 写入端的实体将使用另一个实体的写入端 Guid PK 作为其 FK。当您为这个新的依赖实体发出事件时,您会希望读取端能够将关系建立回主体。

      【讨论】:

      • 我的想法和你一样,但我的朋友有一次告诉我“不要在微服务之间共享 PK”。而且我不知道他为什么这么说。因此,我质疑自己.. 可能他不太了解微服务。我只是想知道没关系,不是什么大问题。
      • 如果您使用数据库生成的 INT id 作为您的 PK,那么,是的,一致地重复使用相同的 ID 可能会有点挑战。但是您使用的是 Guid,所以这对您来说不是问题。
      • 明白了,谢谢。
      猜你喜欢
      • 2017-04-18
      • 1970-01-01
      • 2020-04-25
      • 2019-08-16
      • 2019-06-05
      • 2014-11-19
      • 2018-08-03
      • 2016-01-21
      • 2018-02-17
      相关资源
      最近更新 更多