Modelli per la versione dei dati relazionali in un database MySQL?

11

Sto cercando di trovare un approccio per un progetto, in cui un utente può modificare i record ed essere in grado di vedere le versioni precedenti di tali record. Ecco uno schema di esempio semplificato, che utilizza un elenco:

TABLE list (
  id int auto_increment primary key,
  user_id int, 
  title varchar(255)
);

TABLE list_tasks (
  id int auto_increment primary key,
  list_id int,
  title varchar(255),
  order int,
  is_complete tinyint
);

Quindi un utente può entrare e apportare diverse modifiche all'elenco (ad esempio, aggiungere o rimuovere attività, riordinare attività, contrassegnarne alcune complete, rinominare alcune, ecc.), quindi salvarle. A questo punto, mi piacerebbe generare una "versione 2" dell'elenco e delle attività e far sì che siano in grado di visualizzare le versioni precedenti, ma quando accedono all'elenco, ottengono sempre l'ultima versione.

Esiste un approccio / modello di progettazione comune per gestire i dati delle versioni in questo modo in un database MySQL?

    
posta GSto 28.02.2012 - 20:33
fonte

3 risposte

9

È piuttosto comune volerlo fare in un db. Sebbene tu stia facendo una svolta in quanto vuoi monitorare una revisione per un elenco di elementi.

Un modo per farlo potrebbe essere quello di modificare la struttura come

Alter table lists add revision_id integer;
Alter table list_tasks add revision_id integer;

Create Table revisions
{
   id int autoincrement... (revision id)
   list_id int...
   revdate datetime...
}

Quando l'utente salva il suo elenco, crea una nuova revisione nella tabella revisions sopra e assegna quel valore agli elementi dell'elenco in list_tasks e quindi all'ID di revisione in lists per contrassegnarlo come ' attuale 'revisione. Quando l'utente modifica gli articoli, non modificare gli articoli esistenti, piuttosto, inserirne di nuovi con un nuovo id di revisione e aggiornare la tabella list con quella revisione per contrassegnarla come quella corrente.

Quindi per elencare gli elementi correnti, elenca gli elementi dall'ID di revisione corrente specificato nella tabella lists . Per sfogliare le versioni precedenti, puoi ottenere un elenco delle precedenti revisioni degli elenchi dalla tabella delle revisioni e quindi elencare i singoli elementi in base a tale id.

    
risposta data 28.02.2012 - 20:50
fonte
5

Questa soluzione utilizza una tabella di controllo separata. Ha pro e contro. Potresti preferire eliminare i vecchi record dalla tua tabella principale. Il miglioramento delle prestazioni può essere trascurabile.

Aggiungi i seguenti campi a ciascuna tabella controllata:

AddUserID      int <whatever your system uses>
AddDateTime    datetime
UpdateUserID   int <whatever your system uses>
UpdateDateTime datetime
CurrentVersion int
IsDeleted      bit

Sarà necessario aggiornare questi campi ogni volta che i dati cambiano. CurrentVersion viene incrementato di 1 (Potrebbe essere usato come un modo per bloccare un record, ma questa è un'altra domanda.) IsDeleted fornisce un "soft delete" in modo che possa essere referenziato in futuro.

Tabelle di controllo separate Ogni tabella dovrebbe avere una corrispondente _Archive o _Storia versione della tabella. Questi probabilmente non hanno bisogno di essere indicizzati allo stesso modo. Ovviamente non si applica un singolo campo chiave primaria. Dovresti essere in grado di creare una chiave composta fuori dal campo ID e UpdateDateTime.

Uso di un trigger (Questo risolverà le modifiche apportate all'interno o all'esterno del codice. Puoi decidere se questo funziona per la tua situazione.) o altro codice, quando un record viene aggiunto, aggiornato o cancellato, una copia del record viene inserita nella tabella archivio / cronologia. Tutte le versioni e gli altri campi di controllo sono mantenuti. Questo ti dirà cosa hanno fatto gli utenti quando. La tabella può essere confrontata a se stessa per vedere quando un record è stato modificato o per vedere le tendenze.

Ho visto questo lavoro bene negli ultimi anni. Mi piacerebbe sapere degli svantaggi che forse non sto considerando.

    
risposta data 28.02.2012 - 22:00
fonte
-2

Ti suggerisco di leggere questo articolo ben dettagliato.

link

Un altro approccio è quello di avere una colonna version_id nella tabella e un flag 'current' che specifica quale riga è quella corrente. Ogni volta che hai bisogno di un aggiornamento, puoi inserire una nuova riga e impostare il flag "corrente" della versione esistente su 0 / falso e la riga appena aggiunta su 1.

In questo modo puoi creare una vista che mostra solo quelli con il flag attuale.

    
risposta data 16.11.2016 - 09:57
fonte

Leggi altre domande sui tag