Mijn keuze zou een variatie van benadering 2 zijn. Vet geeft velden in de primaire sleutel aan.
- U plaatst elk artikel in een tabel
articles_versioned
(id , tijdstempel , naam, tekst) - Uw tweede tabel is
articles
(id , tijdstempel, [naam, tekst]). Merk op hoe tijdstempel niet primair is; naam en tekst kunnen worden gerepliceerd, of u kunt een join gebruiken metarticles_versioned
(wat snel zal zijn aangezien id en tijdstempel dearticles_versioned
zijn primaire sleutel) articles_versioned
heeft een trigger bij invoegen die de zojuist ingevoegde rij neemt en repliceert oparticles
- Om een specifieke versie van een artikel te herstellen, wijzigt u de
articles
tafel.
De voordelen van deze aanpak zijn:
- Je krijgt gratis andere informatie (de datum en tijd van het artikel) in je tabel, die je misschien toch nodig hebt
- U hoeft de database niet te doorzoeken om de huidige datum te krijgen. Als je een versie gebruikt, moet je dat ook doen.
- Uw code hoeft het artikel niet in twee tabellen in te voegen. Je voegt gewoon in
articles_versioned
en lees uitarticles
, zorgt de db voor het migreren van gegevens terwijl u deze invoert via de trigger, waardoor consistentieproblemen worden vermeden.
Nadelen
- In een omgeving met veel gelijktijdigheid kunnen twee versies tegelijkertijd worden ingevoegd, dus een ervan kan mislukken. Dit zou geen probleem moeten zijn bij het invoegen van door gebruikers geschreven artikelen (het is tegenwoordig hoogst onwaarschijnlijk gezien de precisie van tijdstempels). Als u de tijdstempel niet opgeeft in uw
INSERT
statement, maar in plaats daarvan stelt u het datetime-veld in om de huidige tijd als standaardwaarde te hebben, kunt u dit probleem volledig vermijden.
Om de rest van je vraag te beantwoorden. Benadering 1 zal niet leiden tot langere zoekopdrachten zolang u een index op status toevoegt. Dit heeft alleen zin als je de neiging hebt om veel verschillende versies van elk artikel te hebben; zolang je gemiddeld of minder 2 versies per artikel hebt, zal de index je alleen maar vertragen, en benadering 2 zou sowieso niet verstandig sneller zijn (hoewel ik mijn benadering nog steeds zou aanbevelen omdat het code eenvoudigweg waardeert, aangezien het herstellen van een versie niet geen schakelstatus nodig voor twee rijen).
Gerelateerde bronnen, zoals afbeeldingen, zouden een vergelijkbare versie moeten volgen. Ik neem aan dat je ze opslaat op het bestandssysteem; in plaats van ze op te slaan met hun echte naam, gebruik je een tabel (id , image_name) om aan elke afbeelding een id te geven en sla de afbeelding vervolgens op als -id-.jpg
. In het veld image_name weet je wat de originele bestandsnaam was (als je daar om geeft). Op deze manier kun je afbeeldingen op dezelfde manier versieren als je versie-artikelen, en in artikelen zou je iets als <img src="-id-.jpg">
gebruiken , waarvan je weet dat ze voor altijd beschikbaar zullen blijven.