Utilizzo di audit trail come macchina del tempo?

4

Mi piacerebbe fare

SELECT * TABLE t (using data from 1st of march 2012)

Ho già un buon audit trail di tutte le tabelle nel database. In pratica fa una copia di tutte le righe che cambiano, memorizzando tutte le colonne della riga modificata in una colonna di hstore. Ciò significa che abbiamo i dati disponibili, ma non sono sicuro se sia il modo migliore per archiviare i dati per una macchina del tempo del database.

Per darti più contesto, stiamo creando un software di contabilità. Ciò significa che dobbiamo essere in grado di ricreare tutti i rapporti che abbiamo offerto al cliente (possono vederli sul nostro sito Web e aggiornarsi continuamente).

Quali tipi di problemi prevedi che mi imbatterò in questo approccio? C'è un approccio migliore?

Alcuni fatti

  • Ogni riga nella tabella principale viene modificata 5 volte in media.
  • La tabella principale ha 32 colonne (potrebbe ridursi a soli 7 che richiedono un audit trail)
  • Avremo sempre un milione di utenti sul nostro software, ognuno avrà ~ 700 righe nella tabella principale.
posta David 04.12.2014 - 14:44
fonte

2 risposte

2

Ecco il mio approccio preferito:

  • Ogni tabella ha una tabella cronologica corrispondente
  • Scrivi stored procedure (o trigger) per assicurarti che tutte le azioni siano registrate nelle tabelle della cronologia
  • Inserito, aggiungi una riga alla tabella della cronologia con start = now () e end = 31.12.2999
  • Durante l'aggiornamento, per prima cosa aggiorna il record della cronologia più recente per terminare = now (). Quindi inserisci una nuova riga con start = now () e end = 31.12.2999
  • Se elimini, aggiorna il record cronologia più recente per terminare = now ().

Ora puoi scrivere una query temporizzata, anche con i join:

select g.groupname, p.productname, p.price 
from products_hist p, product_groups_hist g 
where p.id = g.id 
and p.start <= now() and now() < p.end
and g.start <= now() and now() < g.end
    
risposta data 15.12.2014 - 10:04
fonte
2

Vorrei offrire un approccio diverso rispetto alla risposta accettata in base al sourcing di eventi + cqrs.

L'individuazione degli eventi è un approccio diverso rispetto a quello della progettazione relazionale. Fondamentalmente hai solo un tavolo che possiamo chiamare eventi. Un evento è qualcosa che è accaduto al passato. I.e ContoCreated MoneyDeposited. Questi eventi sono classi che serializzi in testo con il tuo serializzatore preferito. Gli eventi hanno un ordine definito che significa che possiamo costruire qualcosa in cima.

CQRS significa comando di segregazione della resposabilità della query. Significa che abbiamo due modelli. Uno per scrivere e uno per leggere. Concentriamoci sul modello di scrittura. Ogni volta che vuoi cambiare il tuo oggetto, salvi un evento nello stream. Diciamo che salviamo un evento MoneyDeposited. Facciamo un gestore di eventi all'interno della nostra classe. Un esempio semplicissimo potrebbe assomigliare a questo (manca un'infrastruttura).

class BankAccount{
    long Balance{get;set;}
    void Deposit(long amount){SaveEvent(new MoneyDeposited(AccountId,amount); }
    void Apply(MoneyDeposited m){balance += m.Amount; }
}

Dato che ora abbiamo diviso il metodo apply, possiamo leggere un intero stream da db che chiama solo Apply ().

Ciò significa che possiamo facilmente verificare le regole di coerenza. Diciamo che il metodo WithDraw () ha fondi insuffici. Lancerà prima di pubblicare l'evento. Possiamo anche usare facilmente la concorrenza ottimistica per verificare che due oggetti vengano modificati contemporaneamente portando a incongruenze poiché leggiamo la riga n da db incrementiamo la riga in memoria a n + 1 e quindi un semplice indice univoco fallirà se qualche altro thread ha scritto quella riga prima di noi.

Questo è tutto semplificato un po ', ma il tuo obiettivo era usare una macchina del tempo e con i flussi basta scegliere il numero di riga che vuoi leggere e ignorare qualsiasi cosa più recente.

Non ho ancora toccato l'evento con i modelli letti, ma un lungo archivio breve è che in qualche altro archivio costruisci una serie di rappresentazioni basate sugli eventi pronti da mangiare.

Alcuni keyworks per iniziare. Sourcing di eventi CQRS. Prova a trovare le presentazioni di Gregg Young, Udi Dahan e Rinat Abdullin. Alcuni framework utili: NEventStore (.NET) o Cirqus (.NET) anche se è piuttosto giovane.

    
risposta data 15.12.2014 - 13:32
fonte