Aggiornamento di alcuni record del database mantenendo i vecchi valori

0

Sto progettando un'applicazione per più utenti. I loro dati (ad esempio Cognome) potrebbero cambiare nel tempo. Ma i documenti che creano dovrebbero contenere i loro dati per il momento in cui sono stati creati. Per ora sto aggiungendo un nuovo record per qualsiasi cambiamento nei dati degli utenti tranne quelli che cambiano password o scadenza dell'account. Quindi se il record del documento è "firmato" con userid ad es. 25 ottengo dati utente "25" ma dopo che lui / lei ha cambiato qualcosa, il prossimo documento sarà "firmato" con id 26. La mia preoccupazione è che in questo modo sto ottenendo molti record utente "tutti" identici. Ho creato un vincolo univoco per i campi (userId, Active = true). Questo è un buon approccio? Potrei renderlo migliore?

    
posta Vancalar 18.03.2017 - 23:41
fonte

2 risposte

1

Dopo alcune ricerche ho scoperto che il problema che ho descritto è chiamato Dimensione a variazione lenta (SCD) come descritto in molte fonti, come wikipedia: Slowly_changing_dimension e le soluzioni maggiormente utilizzate sono:

  • Tipo 0: conserva originale
  • Tipo 1: sovrascrivi
  • Tipo 2: aggiungi nuova riga
  • Tipo 3: aggiungi un nuovo attributo
  • Tipo 4: aggiungi la tabella della cronologia
  • Tipo 6: ibrido

Il mio attuale aggiornamento utilizza una soluzione di tipo ibrido; È interessante notare che
SQL standard SQL: il 2011 introduce una nuova funzionalità: supporto dati temporali che si occupa di "dati storici" e consente query come:

SELECT * FROM customers AS OF SYSTEM TIME TIMESTAMP '2015-01-22' ;

Questo è descritto nel wiki di postgres:

Dati temporali & Timetravel in Postgresql

C'è anche un modo interessante per raggiungere questo obiettivo dato da iTollu salvando i dati come serie di eventi, che potrebbero essere successivamente "ricalcolati" per trovare lo stato in un dato momento.

Saluti

    
risposta data 20.03.2017 - 00:39
fonte
3

Quello che stai cercando è il concetto di Event Sourcing (ES). Combina abbastanza bene con un altro grande concetto: Domain Driven Design (DDD).

In DDD una "cosa", identificata da Id (come Utente o Conto) è chiamata Entità. Lo stato di un'entità cambia come risultato dell'elaborazione del comando di dominio (come "ChangeSurnameCommand"). Solitamente si convalida un comando, si apportano alcune modifiche all'entità correlata e lo si mantiene nel DB. La modifica stessa costituisce un evento (ad esempio, CognomeChangedEvent).

Ma invece di memorizzare lo stato corrente di un'entità nel DB, è possibile memorizzare tutti gli eventi correlati (ad esempio come campo JSON o XML). Quindi lo stato di un'entità - non solo corrente, ma per un dato momento T - può essere calcolato come listOfEvents.foldLeft(InitialState)(applyEvent) . Cioè prendi un elenco di eventi, prendi uno stato iniziale, prendi una funzione che applica gli eventi e applicali uno per uno allo stato iniziale.

In questo modo ottieni traccia storica, puoi viaggiare nel tempo sullo stato di un'entità, testare e debuggare le singole transizioni di stato.

Questo concetto di Event Sourcing proviene da soluzioni aziendali (come la contabilità) molto prima dei computer. Ma nella comunità IT i primi pionieri a portarlo a noi sviluppatori moderni sono stati Greg Young e Udi Dahan. Puoi effettuare ricerche su YouTube per alcune fantastiche presentazioni.

Domain-Driven Design è stato introdotto da Eric Evans quasi 15 anni fa e ha ottenuto un secondo respiro con la combinazione di microservizi, programmazione funzionale e sourcing di eventi (e approccio CQRS strettamente correlato).

Per quanto mi riguarda, la soluzione ideale per l'archiviazione degli eventi è ancora da trovare. Per "ideale" intendo distribuito e coerente. La direzione del pensiero qui è che ci può essere un tipo di eventi che non devono essere linearizzabili e un altro tipo che è richiesto. Combinato con scalabilità, distribuzione e robustezza può diventare piuttosto interessante. Ma nel caso semplice Postgres (con il suo LIVELLO DI ISOLAMENTO LIVELLO LINEARIZZABILE) andrebbe bene.

Ma prima di pensare allo storage ti consiglio di cercare le presentazioni su YouTube e approfondire un po 'il concetto: vedrai se è adatto alle tue esigenze.

    
risposta data 19.03.2017 - 00:53
fonte

Leggi altre domande sui tag