Схема реляционной базы данных для поиска событий

Я пытаюсь хранить события домена в базе данных postgres. Я не уверен во многих вещах и не хочу переделывать эту структуру позже, поэтому я ищу совета у людей, имеющих опыт работы с источниками событий. В настоящее время у меня есть следующая таблица:

domain events
    version - or event id, integer sequence, helps to maintain order by replays
    type - event type, probably classname with namespace
    aggregate - aggregate id, probably random string for each aggregate
    timestamp - when the event occured
    promoter - the promoter of the event, probably user id
    details - json encoded data about the properties

В чем я не уверен:

  1. Должен ли я хранить промоутер события домена?
    Это может помочь найти скомпрометированную учетную запись из-за нарушений безопасности, но я не знаю, что хранить, например, с помощью CRONjob.
  2. В каком формате хранить тип события?
    Должен ли я добавить таблицу с типами событий или достаточно имен классов?
    Должен ли я добавлять группы событий?
  3. Меня смутило определение ограниченных контекстов. Насколько мне известно, у каждого агрегата может быть несколько ограниченных контекстов, поэтому я могу использовать разные аспекты одного агрегата в нескольких модулях. Звучит неплохо, поскольку, например, учетные записи могут быть связаны со многими вещами, включая аутентификацию, авторизацию, профиль пользователя, сообщения пользователей, пользовательские контракты и т. д....
    В чем я не уверен, что событие домена может иметь несколько ограниченные контексты или только один, поэтому должен ли я также хранить контексты событий? (для случаев, когда я хочу воспроизвести события, связанные с одним контекстом)
    Как реализовать так много свойств в одном агрегатном классе, должен ли я использовать какую-то композицию?

person inf3rno    schedule 03.05.2014    source источник
comment
стр. 41 /а> . Просто для информации, я не очень разбираюсь в поиске событий   -  person Tudor    schedule 03.05.2014
comment
если вы используете .net, есть библиотека NEventStore, которая сделает это за вас. Если нет, попробуйте воспользоваться GetEventStore, созданным Грегом Янгом.   -  person MikeSW    schedule 03.05.2014
comment
Спасибо, почитаю, может быть найду ответы на некоторые вопросы.   -  person inf3rno    schedule 03.05.2014


Ответы (1)


1. Должен ли я хранить промоутер события домена?

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

Например:

ManualPaymentMadeEvent { //store this object as details in your schema
    amount,
    by_user//In this case, developers can determine whether store the promoter case by case
}

2.в каком формате хранить тип события?
Должен ли я добавить таблицу с типами событий или достаточно имен классов? Должен ли я добавлять группы событий?

Я думаю, что имен классов достаточно. Добавление другой таблицы усложняет чтение событий (по таблицам соединений), и я думаю, что это добавляет значение только при переименовании имен классов (обновление одной строки в таблице типов событий). Но я думаю, что это не добавит особых проблем с использованием

update domain_events set 
    aggregate_type = 'new class name'
where aggregate_type = 'origin class name'

Я не уверен, что понимаю группы событий, не могли бы вы добавить больше пояснений?

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

Иногда события используются для интеграции нескольких контекстов. Но каждое событие поднимается только в одном контексте. Например, событие ManualPaymentMadeEvent вызывается в контексте заказа, и список событий в контексте доставки также использует его, рассматривая его как триггер начала доставки.

Я предпочитаю использовать для каждого пользователя базы данных (термин оракула) для каждого контекста. shipping.domain_events для контекста доставки и ordering.domain_events для контекста заказа.

Вот схема в axon-framework, которая может помочь

create table DomainEventEntry (
    aggregateIdentifier varchar2(255) not null,
    sequenceNumber number(19,0) not null,
    type varchar2(255) not null,  --aggregate class name
    eventIdentifier varchar2(255) not null,
    metaData blob,   
    payload blob not null, -- details
    payloadRevision varchar2(255),
    payloadType varchar2(255) not null, --event class name
    timeStamp varchar2(255) not null
);

alter table DomainEventEntry
    add constraint PK_DomainEventEntry primary key (aggregateIdentifier, sequenceNumber, type);
person Yugang Zhou    schedule 04.05.2014
comment
Спасибо! Я сделаю упрощенный дизайн, вдохновленный аксоном. :-) - person inf3rno; 04.05.2014
comment
О, кстати. Можете ли вы предложить какие-либо книги или статьи о контекстном отображении? (Трудно найти теоретические тексты об этом, но люди обычно упоминают об этом или, по крайней мере, ограничивают контексты ddd.) - person inf3rno; 04.05.2014
comment
Дизайн на основе домена и Реализация дизайна, управляемого доменом, имеют отдельную главу этой темы. - person Yugang Zhou; 04.05.2014
comment
@Hippoom Использует ли платформа Axon только одну таблицу (DomainEventEntry в нашем примере) для хранения всех событий из всех типов агрегатов в системе? - person Songo; 02.11.2014
comment
@Songo По умолчанию да. Но вы также можете использовать одну таблицу для каждого совокупного корня с помощью пользовательского объекта jpa, начиная с версии 2.2, issue связанные - person Yugang Zhou; 02.11.2014
comment
@Hippoom Можно ли разделить эту таблицу так, чтобы каждый ограниченный контекст имел свои агрегаты в отдельном сегменте? Моя цель — сделать каждый ограниченный контекст сервисом со своей автономной базой данных. - person Songo; 02.11.2014