Gegevensarchivering is een van de belangrijkste taken voor zwaarbelaste OLTP-systemen met grote tabellen. Historisch gezien waren de eerste pogingen om dit te implementeren extreem eenvoudig: gegevens werden handmatig verwijderd of gekopieerd naar aparte tabellen via scripts of applicaties. Later kwamen er meer systematische benaderingen die rekening hielden met transactionele integriteit en minimale invloed op de hoofdbewerking van de database.
Het probleem hier ligt niet alleen in de fysieke overdracht van informatie, maar ook in het handhaven van consistentie, het minimaliseren van vergrendelingen en het waarborgen van hoge prestaties. Fouten bij archivering kunnen leiden tot gegevensverlies, vergrendeling van gebruikers of een aanzienlijke toename van de belasting.
De oplossing is het gebruik van batch-bewerkingen met transactionele controle, evenals het opzetten van speciale archieftabellen met een identieke structuur, of automatisering via taakplanners en procedures.
Voorbeeld van code:
-- Verplaatsen van 5000 records ouder dan een jaar naar de archieftabel INSERT INTO archive_orders SELECT * FROM orders WHERE order_date < DATEADD(year, -1, GETDATE()) AND id IN (SELECT TOP 5000 id FROM orders WHERE order_date < DATEADD(year, -1, GETDATE()) ORDER BY id); DELETE FROM orders WHERE id IN (SELECT TOP 5000 id FROM orders WHERE order_date < DATEADD(year, -1, GETDATE()) ORDER BY id);
Belangrijke kenmerken:
Wat is het risico bij massaal DELETE van oude records en hoe vermijd je dit?
Massaal DELETE kan leiden tot escalatie van vergrendelingen en vertraging van de werking van de hele database. Dit kan worden vermeden door verwijderingen in kleine porties binnen een lus uit te voeren of met behulp van LIMIT/TOP, indien ondersteund door de DBMS.
WHILE 1=1 BEGIN DELETE TOP (1000) FROM orders WHERE order_date < '2023-01-01'; IF @@ROWCOUNT = 0 BREAK; END
Kan je TRUNCATE gebruiken om geautomatiseerde gegevens te verwijderen?
TRUNCATE verwijdert alle rijen in een tabel en is niet geschikt voor conditionele schone bepaalde rijen. Het roept geen triggers op, ondersteunt geen WHERE en wordt alleen gebruikt voor volledige schoonmaak, niet voor selectieve archivering.
Hoe garandeer je dat de overdracht correct is verlopen als verwijdering en invoer in verschillende transacties plaatsvinden?
Het is beter om de overdracht van rijen in één transactie uit te voeren: eerst kopiëren naar het archief, dan verwijderen uit de hoofd. Anders kan er inconsistentie ontstaan in geval van een storing tussen operaties.
BEGIN TRANSACTION INSERT INTO archive_orders SELECT * FROM orders WHERE ... DELETE FROM orders WHERE ... COMMIT
Een ingenieur draait een script voor een miljoen records DELETE FROM logs WHERE event_date < '2022-01-01' tijdens kantooruren.
Voordelen:
Nadelen:
Gepland overbrengen van 5000 rijen via een opgeslagen procedure en een taak volgens schema 's nachts, met logging van het succes van elke partij.
Voordelen:
Nadelen: