Лучшая стратегия поиска событий db

Я хочу установить небольшую библиотеку источников событий. Я прочитал несколько учебных пособий в Интернете, пока все понятно.

Единственная проблема состоит в том, что в этих разных уроках есть две разные стратегии базы данных, но без каких-либо комментариев, почему они используют ту, которую используют.

Итак, я хочу спросить ваше мнение. И важно, почему вы предпочитаете выбранное вами решение.

  1. Решением является структура БД, в которой вы создаете одну таблицу для каждого события.

  2. Решением является структура базы данных, в которой вы создаете только одну общую таблицу и сохраняете события в виде сериализованной строки в один столбец.

В обоих случаях я не уверен, как они обрабатывают изменения событий, может быть, они создают совершенно новую.

С уважением

Ответ 1

Я создал свою собственную библиотеку источников событий и выбрал вариант 2, и вот почему.

  • Вы запрашиваете поток событий по совокупному идентификатору, а не по типу события.
  • Воспроизведение событий по порядку было бы затруднительно, если бы они все были в разных таблицах
  • Это сделало бы обновление событий немного болезненным

Есть аргумент, что вы можете хранить события для каждого агрегата, но это зависит от требований проекта.

У меня есть несколько сообщений о том, как используются потоки событий, которые могут оказаться вам полезными.

Ответ 2

Решение - это структура db, в которой вы создаете только одну общую таблицу и сохраняете события как сериализованную строку в один столбец

Это, безусловно, лучший подход, поскольку повторные события проще. Теперь мои два цента на получение источников событий: это отличный образец, но вы должны быть осторожны, потому что не все так просто, как кажется. В системе, над которой я работал, мы сохранили поток событий на агрегат, но у нас все еще был набор нормализованных таблиц, потому что мы просто не могли согласиться с тем, что для получения последнего состояния объекта нам нужно было бы запускать все события (снимки помогают, но не являются идеальным решением). Итак, да, источник событий - это прекрасный шаблон, он дает вам полное управление версиями ваших сущностей и полный журнал аудита, и он должен использоваться только для этого, а не как замена набора нормализованных таблиц, но это всего лишь мои два центов.

Ответ 3

Думаю, лучшее решение будет состоять в # 2. И даже вы можете сохранить свое текущее состояние вместе со связанным событием в одно и то же время, если вы используете транзакционный db, такой как mysql.

Я действительно не люблю и рекомендую решение # 1.

Если ваша проблема в # 1 связана с версией/обновлением событий; затем объявите новый класс для каждого нового изменения. Не будьте слишком ленивы; или быть одержимым повторным использованием. Сообщите подписчикам об изменениях; дать им версию события.

Если ваши участники для # 1 - это что-то вроде запросов/интерпретации событий; то позже вы можете легко вставлять свои события в nosqldb или eventstore в любое время (от исходного db).

Также; шаблон, который я использую для eventourcing lib, выглядит примерно так:

public interface IUserCreated : IEventModel
{

}

public class UserCreatedV1 : IUserCreated
{
    public string Email { get; set; }
    public string Password { get; set; }
}

public class UserCreatedV2 : IUserCreated
{
    // Fullname added to user creation. Wrt issue: OA-143

    public string Email { get; set; }
    public string Password { get; set; }
    public string FirstName { get; set; }
    public string LastName { get; set; }
}

public class EventRecord<T> where T : IEventModel
{
    public string SessionId { get; set; } // Can be set in emitter.
    public string RequestId { get; set; } // Can be set in emitter.
    public DateTime CreatedDate { get; set; } // Can be set in emitter.
    public string EventName { get; set; } // Extract from class or interface name.
    public string EventVersion { get; set; } // Extract from class name
    public T EventModel { get; set; } // Can be set in emitter.
}

public interface IEventModel { }

Итак, сделать обновление версий событий и обновление явным; как в домене, так и в кодовой базе. Внедрить обработку новых событий в подписчиках перед развертыванием новых событий. А также; если не требуется, не разрешают прямое потребление событий домена от внешних абонентов; поместите слой интеграции или что-то в этом роде.

Я хочу, чтобы мои мысли были полезны для вас.

Ответ 4

Я прочитал о подходе к организации событий, который состоит из:

  • с двумя таблицами: aggregate и event;
  • база для вас также используется:

    а. создает и регистрирует таблицу агрегатов, генерируя идентификатор, версию = 0 и тип события и создавая событие в таблице событий;

    б. извлекать из сводной таблицы, события по идентификатору или типу события, применять бизнес-кейсы, а затем обновлять сводную таблицу (версию и тип события), а затем создавать событие в таблице событий.

хотя я этот подход обновляет некоторые поля в таблице aggregate, он оставляет таблицу событий только как добавленную и улучшает производительность, поскольку у вас есть последняя версия агрегата в таблице агрегатов.

Ответ 5

Я бы пошел С# 2, и если вы действительно хотите иметь эффективный способ поиска по типу события, я бы просто добавил индекс в этот столбец.

Ответ 6

Вот две стратегии для доступа к данным о предмете, вовлеченном в этот случай. 1) текущее состояние и 2) последовательность событий. В текущем состоянии мы обрабатываем события, но сохраняем только последнее состояние объекта. С помощью последовательности событий мы сохраняем события и перестраиваем текущее состояние, обрабатывая события каждый раз, когда нам нужно это состояние. Последовательность событий более надежна, поскольку мы можем отслеживать все, что произошло, вызывая текущее состояние, но оно определенно неэффективно. Здравый смысл также сохранять промежуточные состояния (снимки) не только последними, чтобы избежать постоянной повторной обработки всех событий. Теперь у нас есть надежность и производительность.

В криптовалютах есть последовательность событий и локальные моментальные снимки - локальное в названии происходит потому, что цепочки блоков распределены, а данные реплицированы.