La mia scelta sarebbe una variazione dell'approccio 2. Il grassetto indica i campi nella chiave primaria.
- Inserisci ogni articolo in una tabella
articles_versioned
(id , indicatore orario , nome, testo) - La tua seconda tabella è
articles
(id , timestamp, [nome, testo]). Nota come il timestamp non sia primario; nome e testo possono essere replicati oppure puoi utilizzare un join conarticles_versioned
(che sarà veloce poiché id e timestamp sonoarticles_versioned
chiave primaria) articles_versioned
ha un trigger all'inserimento che prende la riga appena inserita e la replica suarticles
- Per ripristinare una versione specifica di un articolo, modifichi gli
articles
tabella.
I vantaggi di questo approccio sono:
- Ottieni gratuitamente un'altra informazione (la data e l'ora dell'articolo) nella tua tabella, di cui potresti comunque aver bisogno
- Non è necessario interrogare il database per ottenere la data corrente. Se usi la versione, devi farlo.
- Il tuo codice non deve inserire l'articolo in due tabelle. Inserisci semplicemente in
articles_versioned
e leggi daarticles
, il db si occupa della migrazione dei dati man mano che li inserisci tramite il trigger, evitando qualsiasi problema di coerenza.
Contro
- In un ambiente fortemente simultaneo, due versioni possono essere inserite contemporaneamente, quindi una di esse potrebbe non funzionare. Questo non dovrebbe essere un problema quando si inseriscono articoli scritti dagli utenti (di questi tempi è altamente improbabile data la precisione dei timestamp). Se non specifichi il timestamp nel tuo
INSERT
istruzione, ma invece imposti il campo datetime in modo che abbia l'ora corrente come valore predefinito, potresti evitare del tutto questo problema.
Per rispondere al resto della tua domanda. L'approccio 1 non porterà a query più lunghe finché si aggiunge un indice sullo stato. Questo ha senso solo se tendi ad avere molte versioni diverse di ogni articolo; fintanto che hai in media 2 versioni per articolo o meno, l'indice ti rallenterà e l'approccio 2 non sarebbe comunque sensibilmente più veloce (anche se consiglierei comunque il mio approccio perché semplifica il codice, poiché il ripristino di una versione lo fa non richiedono lo stato di commutazione per due righe).
Le risorse correlate, come le immagini, dovrebbero seguire una versione simile. Presumo che tu li stia salvando sul filesystem; invece di salvarli con il loro vero nome, usa una tabella (id , image_name) per assegnare a ciascuna immagine un ID, quindi salvare l'immagine come -id-.jpg
. Il campo image_name ti consentirà di sapere qual era il nome del file originale (se ti interessa). In questo modo puoi eseguire la versione delle immagini allo stesso modo della versione degli articoli e negli articoli utilizzeresti qualcosa come <img src="-id-.jpg">
, che sai resterà disponibile per sempre.