Репортажи в мире CQRS/ES

Я думаю, что понимаю идею модели чтения в контексте ES + CQRS (пожалуйста, исправьте меня, если нет). Тем не менее, у меня все еще есть некоторые сомнения относительно использования его в контексте "серьезной" отчетности. Допустим, я использую реляционную базу данных плюс немного ORM для того, чтобы читать мои модели чтения. Одна базовая "модель чтения сводной статистики" может выглядеть так:

 class SummaryStats1
    {
    public Guid TypeId { get; set; }
    public string TypeName { get; set; }
    public Guid SubTypeId { get; set; }
    public string SubTypeName { get; set; }
    public int Count { get; set; }
    }

Учитывая событие:

TypeId = 3acf7d6f-4565-4672-985d-a748b7706a3e
TypeName = Bla1
SubTypeId = 41532aa1-f5d1-4ec4-896b-807ad66f75fc
SubTypeName = Bla2

Нормализатор будет:

(1) Проверьте, существует ли экземпляр вышеупомянутой комбинации (определенный с помощью TypeId, TypeName, SubTypeId, SubTypeName) (2) Если такого экземпляра нет, он создал бы экземпляр и установил Count равным единице. Если он есть, это увеличит количество на единицу.

Это приемлемый подход к отчетности? Я полагаю, что можно выполнить очень эффективные операции выбора для этой ненормализованной структуры данных (для фильтрации и других sql-проекций):

SELECT  TypeName, Sum(Count) FROM SummaryStats1 GROUP BY TypeName

Согласятся ли с этим эксперты CQRS/ES? Является ли это "способом" ведения дел (т. Е. Созданием этих специальных моделей чтения отчетов)? Любые ссылки на исходный код / ​​реальные примеры будут очень благодарны.

1 ответ

Решение

Это приемлемый подход к отчетности?

конечно, зависит ли это от способа доставки, в зависимости от ваших требований, но общая идея верна.

В итоге:

Вы генерируете свои модели чтения (иногда используется официальный термин Eager Read Derivation) на основе событий, поступающих с вашего домена.

Модели для чтения могут быть любыми (sql, redis, mongo и т. Д.). Все, что позволяет вашим запросам быть эффективными. Например, в вашем примере нет причины, по которой у вас не может быть двух моделей чтения для еще более эффективного выполнения ваших запросов (хотя того, что вы описываете, вполне достаточно для большинства случаев):

  1. ваш sql вид как описано
  2. предварительно агрегированное представление, сгруппированное по typeName чтобы вам не приходилось делать группу каждый раз по запросу (вместо этого вы вычисляете группировку в нормализаторе).

Короче говоря, нет правильного или неправильного способа построения моделей чтения. Прелесть в том, что вы абсолютно свободны в том, чтобы смоделировать модели, которые вы читаете, любым удобным для вас способом (исходя из представленных вами шаблонов запросов и узких мест производительности), не думая о том, как эти модели влияют на записи (просто потому, что они этого не делают. cqrs разбивает читает и пишет)

Использование событийного поиска в сочетании с CQRS дает еще более приятные возможности, а именно: создавать новые модели чтения и заполнять их данными, просто воспроизводя прошлые события из источника событий.

Просто несколько дополнительных примеров того, что можно считать "моделью чтения" ваших данных:

  • представление INCR с Redis (альтернатива тому, что вы, казалось, описали)
  • Elasticsearch / Solr поисковый индекс
  • KV-магазин / индекс для быстрого поиска по ключу.

Идея еще раз заключается в том, что эти "модели чтения" / представления всегда обновляются (в конечном итоге согласованно) путем отправки на них событий обновления (обычно с помощью pubsub).

Для более хорошего прочтения смотрите ответ плюс ссылки на этот вопрос: Прочтите побочные подходы к реализации с использованием CQRS

Другие вопросы по тегам