【问题标题】:Is it normal for fields on the read database not to appear in the write database?读数据库上的字段不出现在写数据库是正常的吗?
【发布时间】:2019-02-11 21:33:02
【问题描述】:

CQRS 写入数据库包含与 CQRS 读取数据库不同的字段是否正常?比如上面的例子,那么Product.Description在读端(NoSQL)被持久化,而在写端(SQL Server)不被持久化是否正常?

我意识到,写入端选择的数据库 (RDBMS) 可能会以不同于读取端选择的数据库 (NoSQL) 的方式构建数据。我特别询问是否“允许”选择在读取端和写入端持久保存哪些数据字段。

我问的原因是我正在阅读的一本书暗示这是正常的,但是,我在书中或网上找不到任何支持这一点的例子。

请看下面的代码:

public class Product
    {
        public Guid Id { get; set; }
        public string Code { get; set; }
        public string Description { get; set; }

        public void LookupDescriptionByCode(List<ProductDescriptionLookup> productCodes)
        {
            Description = productCodes.Find(x => x.Code == Code).Description;
        }
    }

【问题讨论】:

    标签: c# domain-driven-design cqrs


    【解决方案1】:

    CQRS 写入数据库包含与 CQRS 读取数据库不同的字段是否正常?

    通常,写入数据库将是(大于)读取数据库的超集。

    Product.Description 在读取端(NoSQL)持久化但在写入端(SQL Server)不持久化是否正常?

    不,但也许。

    如果你想象一个系统有一个单一的写入数据库,那么“记录簿”就是写入数据库,一切都将存在于其中;读取数据库将只是写入数据库中信息的缓存副本。

    但是,如果您要拆分该单体,读取模型可能会结合来自多个写入模型的信息。所以写模型可能只知道产品代码,而读模型可能有产品描述(因为它使用代码从“其他地方”查找描述)。

    但是某处在系统中,您在任何给定时间都有“该”产品代码的官方副本。

    我有一个事件日志,它是记录簿。我很困惑为什么还需要写数据库。我可以看到将某些域对象持久化到写入数据库的好处,但不是全部?

    如果您正在进行事件溯源,那么您的事件日志通常存储在您的写入数据库中(可能是 RDBMS,也可能是专用消息存储)。

    公平地说,如果有 EventStore/EventLog/IntegrationLog 则不需要写入数据库(每个域对象的关系表)。

    我认为,如果您的事件存储充当记录簿,那么您不需要关系表充当这些相同实体的记录簿。

    例如,您可以将事件溯源用于您的部分域,而不是全部域。或者您可能希望缓存表示以提高写入效率。或者……

    【讨论】:

    • 我有一个事件日志,它是记录簿。我很困惑为什么还需要写数据库。我可以看到将某些域对象持久化到写入数据库的好处,但不是全部?
    • 感谢您的编辑。 +1。公平地说,如果有 EventStore/EventLog/IntegrationLog 则不需要写入数据库(每个域对象的关系表)。
    • 感谢您最近的编辑。最后,如果我使用事件日志(集成日志)而不是事件存储怎么办。是否也建议使用关系表 - 在我的情况下不需要它们,因为记录在输入后永远不会改变。我相信我正在做没有事件溯源和集成日志的 CQRS。
    猜你喜欢
    • 2013-01-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-10-18
    • 1970-01-01
    • 1970-01-01
    • 2019-07-12
    • 2014-03-30
    相关资源
    最近更新 更多