Domanda

Ho un obbligo di memorizzare tutte le versioni di un'entità in un modo facilmente indicizzato e chiedevo se qualcuno ha input su quale sistema usare.

Senza versioni del sistema è semplicemente un database relazionale con una riga per, ad esempio, persona. Se lo stato della persona cambia quella riga viene modificato per riflettere questo. Con l'entrata delle versioni dovrebbe essere aggiornato in modo tale da poter sempre tornare a una versione precedente. Se ho potuto utilizzare un database temporale questo sarebbe libero e sarebbe in grado di chiedere 'qual è lo stato di tutte le persone a partire da ieri alle 2 del pomeriggio vivere a Dublino e di età compresa tra 30'. Purtroppo non sembra essere alcuni progetti open source maturi che possono fare temporale.

Un modo davvero brutto per farlo è solo per inserire una nuova riga per ogni cambiamento di stato. Questo porta a duplicazioni, come una persona può avere molti campi, ma solo uno che cambia per ogni aggiornamento. E 'anche abbastanza lento quindi per selezionare la versione corretta per ogni persona dato un timestamp.

In teoria dovrebbe essere possibile utilizzare un database relazionale e di un sistema di controllo versione per simulare un database temporale, ma questo suona piuttosto orrendo.

Così mi chiedevo se qualcuno ha incontrato qualcosa di simile prima e come si avvicinarono?

Aggiorna Come suggerito da Aaron ecco la query attualmente usiamo (in mysql). E 'sicuramente lento sulla nostra tavola con> 200k righe. (Id = chiave della tabella, person_id = id a persona, duplicato se la persona ha molte revisioni)

  

selezionare il nome da persona p dove p.id = (selezionare max (id) da persona dove person_id = p.person_id e timestamp <=: timestamp)

Aggiorna Sembra che il modo migliore per farlo è con un db temporale, ma dato che non ci sono quelli open source là fuori il miglior metodo successivo è quello di memorizzare una nuova riga per ogni aggiornamento. L'unico problema è la duplicazione di colonne invariate e la query lente.

È stato utile?

Soluzione

Ci sono due modi per affrontare questo. Sia per scontato che si inseriscono sempre nuove righe. In ogni caso, è necessario inserire un timestamp (created), che ti dice quando una riga è stata "modificata".

Il primo approccio utilizza un numero per contare quante istanze che già avete. La chiave primaria è la chiave oggetto più il numero di versione. Il problema di questo approccio sembra essere che avrete bisogno di un select max(version) per fare una modifica. In pratica, questo è raramente un problema dal momento che per tutti gli aggiornamenti dal app, è necessario caricare la versione attuale della persona, modificarlo (e incrementare la versione) e quindi inserire la nuova riga. Quindi il vero problema è che questo progetto rende difficile eseguire gli aggiornamenti del database (per esempio, assegnare una proprietà da molti utenti).

L'approccio seguente utilizza collegamenti nel database. Invece di una chiave composta, si dà ogni oggetto una nuova chiave e si dispone di un campo replacedBy che contiene la chiave della prossima versione. Questo approccio rende semplice per trovare la versione attuale (... where replacedBy is NULL). Gli aggiornamenti sono un problema, però, dal momento che è necessario inserire una nuova riga e aggiornare uno esistente.

Per risolvere questo problema, è possibile aggiungere un puntatore posteriore (previousVersion). In questo modo, è possibile inserire le nuove righe e quindi utilizzare il puntatore di nuovo per aggiornare la versione precedente.

Altri suggerimenti

Ecco una (un po 'datato) rassegna della letteratura sulle basi di dati temporali: http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.91.6988&rep=rep1&type=pdf

mi sento di raccomandare di spendere un bel po 'seduto con quei riferimenti e / o Google Scholar per cercare di trovare alcune buone tecniche che misura il vostro modello di dati. Buona fortuna!

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top