2015-02-23 10 views
13

Voglio configurare un piccolo evento di distribuzione lib. Ho letto alcuni tutorial online, tutto ciò che ho capito finora.best event sourcing db strategy

L'unico problema è che in questi diversi tutorial ci sono due diverse strategie di database, ma senza commenti perché usano quello che usano.

Quindi, voglio chiedere la tua opinione. E, importante, perché preferisci la soluzione che scegli.

  1. Soluzione è la struttura di db in cui si crea una tabella per ogni evento.

  2. Soluzione è la struttura di db in cui si crea solo una tabella generica e si salvano gli eventi come stringa serializzata su una colonna.

In entrambi i casi non sono sicuro di come gestiscono i cambiamenti degli eventi, forse ne creano uno completamente nuovo.

Cordiali saluti

risposta

22

ho costruito il mio proprio evento di sourcing lib e ho optato per l'opzione 2 ed ecco perché.

  • Si interroga il flusso di eventi per ID aggregato non per tipo di evento.
  • La riproduzione eventi in ordine sarebbe un dolore se sono tutti in tabelle differenti
  • Sarebbe l'aggiornamento di eventi un po 'di dolore

C'è un argomento per dire che si può memorizzare gli eventi su una base per aggregato ma dipende dalle esigenze del progetto.

Ho alcuni post su come vengono utilizzati i flussi di eventi che potrebbero essere utili.

6 Code Smells With Your CQRS Events and How to Avoid Them

Aggregate Root – How to Build One for CQRS and Event Sourcing

How to Upgrade CQRS Events Without Busting Your Event Stream

Spero che troverete che utile.

8

Solution è la struttura db in cui si crea solo una tabella generica, e salvare gli eventi come stringa serializzata ad una colonna

Questo è di gran lunga il miglior approccio, come la riproduzione di eventi è più semplice. Ora i miei due centesimi sul sourcing di eventi: è un grande schema, ma dovresti fare attenzione perché non tutto è così semplice come sembra. In un sistema su cui stavo lavorando abbiamo salvato il flusso di eventi per aggregato ma avevamo ancora un set di tabelle normalizzate, perché non potevamo accettare che per ottenere lo stato più recente di un oggetto dovessimo eseguire tutti gli eventi (le istantanee aiutano ma non sono una soluzione perfetta). Quindi sì, l'event sourcing è un buon modello, ti dà una versione completa delle tue entità e un log di controllo completo, e dovrebbe essere usato solo per quello, non come una sostituzione di un insieme di tabelle normalizzate, ma questo è solo il mio centesimi.

+4

Mantenere una vista aggiornata (eventualmente coerente) delle entità non è incompatibile con il sourcing di eventi, infatti è molto spesso utilizzato insieme. Event sourcing significa semplicemente che gli eventi sono l'unica fonte autorevole dei tuoi dati, quindi le tue visualizzazioni/proiezioni materializzate devono essere derivate da esso. Tratta le viste come una comodità che può essere cestinata/ricostruita in qualsiasi momento e che tu stia bene. – AlexG

+4

Basta completare la risposta, non c'è bisogno di essere scortesi :) – AlexG

+1

In realtà, questo è solo un modo di fare CQRS, che è stato progettato intorno alla comprensione che la costruzione di eventi puri ogni volta potrebbe essere inefficiente in molti casi. –

3

Penso che la soluzione migliore sarà quella di andare con # 2. E anche tu puoi salvare il tuo stato attuale insieme all'evento correlato allo stesso tempo se usi un db transazionale come mysql.

Non mi piace e mi raccomando la soluzione # 1.

Se la preoccupazione per # 1 riguarda la versione/aggiornamento dell'evento; quindi dichiarare una nuova classe per ogni nuova modifica. Non essere troppo pigro; o essere ossessionato dal riutilizzo. Lascia che gli abbonati conoscano i cambiamenti; dare loro la versione dell'evento.

Se i tuoi concorsi per # 1 riguardano qualcosa come query/interpretazione degli eventi; in seguito puoi facilmente inviare i tuoi eventi a un nosqldb o ad un eventstore in qualsiasi momento (dal db originale).

Inoltre; il modello che uso per la creazione di eventi lib è qualcosa del genere:

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 { } 

Quindi; rendere esplicito il controllo delle versioni degli eventi e l'aggiornamento; sia nel dominio che nel codebase. Implementare la gestione di nuovi eventi nei sottoscrittori prima di distribuire l'origine di nuovi eventi. E; se non richiesto, non consentire il consumo diretto di eventi di dominio da parte di utenti esterni; metti un livello di integrazione o qualcosa del genere.

Vorrei che i miei pensieri ti fossero utili.

2

ho letto circa un approccio evento-sourcing che consiste in:

  1. avente due tabelle: inerti ed evento;
  2. in base a casi di utilizzo:

    a. crea e registra sulla tabella aggregata, generando un ID, versione = 0 e un tipo di evento e crea un evento nella tabella degli eventi;

    b. recuperare dalla tabella aggregata, eventi per ID o tipo di evento, applicare casi aziendali e quindi aggiornare la tabella aggregata (versione e tipo di evento) e quindi creare un evento nella tabella degli eventi.

anche se questo approccio aggiorna alcuni campi sulla tabella aggregata, lascia tavolo evento come accodare solo e migliora la performace come avere l'ultima versione di un aggregato nella tabella aggregata.

0

Vorrei andare con il n. 2, e se si vuole veramente avere un modo efficiente di ricerca tramite il tipo di evento, vorrei semplicemente aggiungere un indice su quella colonna.

Problemi correlati