DELETE versus TRUNCATE versus DROP: Verschillen, terugdraaien en wanneer elk te gebruiken
Alle drie de commando’s verwijderen iets, maar ze verwijderen verschillende dingen op verschillende manieren. Hier leest u wat iedereen doet, wat u ongedaan kunt maken en hoe de regels tussen databases veranderen.
- DELETE verwijdert rijen, optioneel gefilterd met WHERE. De tafel blijft.
- TRUNCATE verwijdert alle rijen snel. De tabelstructuur blijft.
- DROP verwijdert de hele tabel: gegevens, structuur, indexen en triggers.
- Rollback, triggers en identiteitsreset gedragen zich in elke database anders, dus controleer die van u.
Een tester wil een faseringstabel leegmaken voordat er opnieuw wordt getest. Moet het DELETE, TRUNCATE of DROP zijn? De verkeerde keuze kan een langzame klus betekenen, een ontbrekende tafel of, tijdens de productie, een zeer slechte middag.
We hebben de onderstaande DELETE- en DROP-voorbeelden uitgevoerd in SQLite 3.50, en de uitvoer komt uit die run. SQLite heeft geen TRUNCATE commando, dus de TRUNCATE-opmerkingen zijn gebaseerd op de officiële PostgreSQL-, MySQL- en SQL Server-documentatie in plaats van op onze eigen test.
Het korte antwoord
- Wilt u enkele rijen verwijderen? Gebruik
DELETE ... WHERE. - Wilt u een tafel leegmaken, maar deze behouden? Gebruik
TRUNCATE, waar dit wordt ondersteund. - Moet de tafel voorgoed weg? Gebruik
DROP TABLE.
DELETE: rijen verwijderen
DELETE is een opdracht voor het wijzigen van gegevens (DML). Het verwijdert rijen één voor één, activeert triggers op rijniveau en kan worden gefilterd. We hebben een kleine tabel opgezet met een audittrigger:
CREATE TABLE logs (id INTEGER PRIMARY KEY AUTOINCREMENT, level TEXT);
INSERT INTO logs (level) VALUES ('INFO'),('ERROR'),('INFO'),('DEBUG');
CREATE TABLE audit (msg TEXT);
CREATE TRIGGER logs_delete AFTER DELETE ON logs
BEGIN INSERT INTO audit VALUES ('deleted ' || OLD.id); END;
DELETE FROM logs WHERE level = 'DEBUG';
SELECT id, level FROM logs; -- (1,'INFO'), (2,'ERROR'), (3,'INFO')
SELECT * FROM audit; -- 'deleted 4'
Alleen de overeenkomende rij ging weg en de trigger registreerde dit. Door DELETE FROM logs uit te voeren zonder een WHERE-clausule werden de andere drie rijen verwijderd, en de audittabel bevatte toen vier vermeldingen, één per verwijderde rij.
DELETE reset de tellers voor automatisch verhogen niet. Nadat we de tabel hadden geleegd, ontving onze volgende insert id 5, niet 1. In SQLite komt dit door AUTOINCREMENT. MySQL InnoDB- en SQL Server-identiteitskolommen gaan ook verder waar ze waren na een DELETE.
Tip: Voer vóór elke DELETE met een WHERE-clausule eerst dezelfde clausule uit als een SELECT COUNT(*). Als de telling je verrast, stop dan. Lees onze handleiding over SQL NULL-waarden voor de traps die NULL maakt in een WHERE-clausule.
TRUNCATE: maak de tabel leeg
TRUNCATE TABLE logs; verwijdert elke rij in één keer. Er kan geen WHERE-clausule in staan. In plaats van rijen één voor één te verwijderen, geeft de database doorgaans de gegevenspagina’s van de tabel vrij. Daarom is dit bij grote tabellen veel sneller.
Toen we het in SQLite uitvoerden, kregen we een syntaxisfout, omdat SQLite de opdracht niet heeft:
TRUNCATE TABLE logs;
-- near "TRUNCATE": syntax error
Gebruik in SQLite DELETE FROM logs; zonder WHERE-clausule. De documentatie van SQLite beschrijft een “truncate-optimalisatie” die dit snel maakt als de tabel geen triggers heeft. Onze tabel had een trigger, dus de verwijdering werd rij voor rij uitgevoerd en voor elke rij geactiveerd.
In databases die TRUNCATE ondersteunen, volgens hun documentatie:
- Normaal gesproken worden er geen DELETE-triggers op rijniveau geactiveerd.
- Meestal worden identiteits- of auto-increment-tellers opnieuw ingesteld, bijvoorbeeld in MySQL en SQL Server. In PostgreSQL voeg je
RESTART IDENTITYtoe. - Het heeft op de meeste systemen sterkere machtigingen nodig dan DELETE.
DROP: verwijder de tafel zelf
DROP TABLE is een schema-opdracht (DDL). Het verwijdert de gegevens, de tabeldefinitie, de indexen, triggers en beperkingen. Alles dat naar de tabel verwijst, zoals views of externe sleutels, wordt ook beïnvloed.
DROP TABLE logs;
SELECT * FROM logs;
-- no such table: logs
DROP TABLE IF EXISTS logs; -- no error, even though it is gone
IF EXISTS is handig bij installatiescripts die meerdere keren kunnen worden uitgevoerd. Weergaven van een verwijderde tabel kunnen kapot gaan, zoals we hebben laten zien in SQL-weergaven uitgelegd.
Vergelijkingstabel
| Functie | VERWIJDEREN | AFKORT | DALEN |
|---|---|---|---|
| Verwijdert | Sommige of alle rijen | Alle rijen | Tabel en rijen |
| WHERE-clausule | Ja | Nee | Nee |
| Type opdracht | DML | DDL (meestal) | DDL |
| Row veroorzaakt vuur | Ja | Meestal nee | Nee |
| Reset identiteit | Nee | Meestal wel | Tafel is weg |
| Snelheid op grote tafels | Langzaam | Snel | Snel |
| Tafel blijft | Ja | Ja | Nee |
Kun je terugrollen?
Dit is waar veel artikelen te simpel zijn. Het eerlijke antwoord is dat het afhangt van de database.
VERWIJDEREN kan overal binnen een transactie worden teruggedraaid. Wij hebben het getest:
BEGIN;
DELETE FROM logs;
SELECT COUNT(*) FROM logs; -- 0
ROLLBACK;
SELECT COUNT(*) FROM logs; -- 3
DROP is ook teruggedraaid in SQLite, dat transactionele DDL ondersteunt:
BEGIN;
DROP TABLE logs;
ROLLBACK;
SELECT COUNT(*) FROM logs; -- 1 (the table is back)
Voor TRUNCATE en DROP in andere databases, volgens hun documentatie:
| Database | TRUNCATE / DROP in een transactie |
|---|---|
| PostgreSQL | Kan teruggedraaid worden. DDL is transactioneel. |
| SQL-server | Kan worden teruggedraaid binnen een expliciete transactie. |
| MySQL | Veroorzaakt een impliciete commit, dus deze kan niet worden teruggedraaid. |
| Orakel | Impliciet committeren. DROP kan mogelijk worden hersteld vanuit de prullenbak. |
Dus “TRUNCATE kan nooit worden teruggedraaid” is verkeerd voor PostgreSQL en SQL Server, en “het kan altijd worden teruggedraaid” is verkeerd voor MySQL. Buiten een transactie kan geen enkele transactie ongedaan worden gemaakt zonder een back-up.
Waarom TRUNCATE snel is
DELETE registreert elke verwijderde rij, zodat de wijziging ongedaan kan worden gemaakt en kan worden gerepliceerd, activeert triggers en controleert beperkingen rij voor rij. Op een tafel met miljoenen rijen levert dat veel werk en logvolume op. TRUNCATE maakt de opslag doorgaans in één handeling ongedaan, waardoor er veel minder wordt geregistreerd. Als u een grote subset wilt verwijderen in plaats van alles, verwijdert u deze in batches, zodat u lange vergrendelingen vermijdt. We behandelen de vergrendelings- en querykosten in SQL-queryoptimalisatie.
Externe sleutels en machtigingen
- Buitenlandse sleutels. SQL Server weigert een tabel TRUNCATE waarnaar wordt verwezen door een externe sleutel. PostgreSQL vereist dat u ook de verwijzende tabellen inkort, of
CASCADEgebruikt. Een DELETE controleert in plaats daarvan elke rij op de beperkingen. - Rechten. DELETE heeft verwijderrechten nodig. TRUNCATE heeft vaak ALTER of een speciaal TRUNCATE-recht nodig, en DROP heeft eigendom of ALTER op het schema nodig.
- Replicatie en audit. Als andere systemen afhankelijk zijn van wijzigingslogboeken of triggers op rijniveau, kan TRUNCATE deze overslaan. Neem eerst contact op met de eigenaar van deze systemen.
Welke te gebruiken
| Situatie | Gebruik |
|---|---|
| Verwijder de geannuleerde bestellingen van een klant | VERWIJDEREN met WAAR |
| Reset een faseringstabel vóór elke testuitvoering | TRUNCATE (of DELETE in SQLite) |
| Zorg ervoor dat audittriggers blijven werken | VERWIJDEREN |
| Verwijder een tafel die niet meer in het ontwerp zit | DROP in een beoordeelde migratie |
| Wis miljoenen oude rijen, maar behoud recente rijen | VERWIJDER in batches, of partitie en verwijder oude partities |
Voor testgegevens is TRUNCATE populair omdat het ID’s opnieuw instelt, waardoor tests herhaalbaar worden. Elke test omsluiten in een transactie die wordt teruggedraaid is een andere optie, die wordt uitgelegd in SQL-transacties en ACID.
Veiligheidscontrolelijst
- Bevestig met welke database en omgeving u bent verbonden.
- Voer eerst de WHERE-clausule uit als SELECT.
- Verpak de wijziging in een transactie waar uw database dit ondersteunt.
- Zorg voor een recente, geteste back-up voordat TRUNCATE of DROP in productie gaat.
- Plaats DROP-instructies in beoordeelde migratiescripts, nooit in ad-hocconsoles.
- Controleer wat er van een tabel afhangt, zoals views, refererende sleutels en rapporten, voordat u deze verwijdert.
Veilig grote hoeveelheden gegevens verwijderen
Het verwijderen van miljoenen rijen met één DELETE kan de tabel lange tijd vergrendelen, het transactielogboek vullen en de replicatie vertragen. Een gebruikelijk patroon is om in kleine batches te verwijderen en te herhalen totdat er niets meer over is:
-- SQL Server style (not run for this article)
DELETE TOP (5000) FROM logs WHERE created_at < '2026-01-01';
-- PostgreSQL style (not run for this article)
DELETE FROM logs
WHERE id IN (SELECT id FROM logs WHERE created_at < '2026-01-01' LIMIT 5000);
Voer de instructie in een lus uit, met een korte pauze tussen batches, totdat er nul rijen worden gerapporteerd. Elke batch is een kleine transactie, dus de vergrendelingen zijn kort en andere zoekopdrachten blijven actief. Een index op de filterkolom, hier created_at, houdt elke batch snel.
Voor gegevens die op basis van de datum groeien, zoals logboeken en gebeurtenissen, is tabelpartitionering zelfs nog beter. Elke maand bevindt zich op zijn eigen partitie, en het verwijderen van oude gegevens wordt een snelle handeling waarbij één partitie wordt verwijderd of ingekort in plaats van rijen één voor één worden verwijderd.
Zachte verwijderingen
Veel applicaties verwijderen nooit fysiek bedrijfsgegevens. Ze voegen een kolom toe zoals deleted_at en stellen deze in plaats daarvan in, en zoekopdrachten filteren vervolgens op deleted_at IS NULL. Zachte verwijderingen maken herstel eenvoudig en houden de geschiedenis bij voor audits, maar elke zoekopdracht moet het filter onthouden, wat goed is voor een weergave. Er is ook zorg nodig voor unieke beperkingen, omdat een zacht verwijderde rij nog steeds zijn waarde behoudt. Privacywetgeving kan vereisen dat persoonlijke gegevens na een bepaalde periode daadwerkelijk worden verwijderd. Zachte verwijderingen zijn dus geen vervanging voor een bewaarbeleid.
Tot slot
DELETE is het precieze, zorgvuldige hulpmiddel. TRUNCATE is de snelle resetknop en DROP verwijdert de tabel volledig. Het grootste risico is dat de ene database zich als de andere gedraagt, vooral als het om rollback gaat. Test bij twijfel eerst het commando op een kopie van de tabel in uw eigen database.
Veelgestelde vragen
Wat is het belangrijkste verschil tussen DELETE en TRUNCATE?
DELETE verwijdert rijen één voor één, ondersteunt WHERE en activeert triggers. TRUNCATE verwijdert alle rijen in één keer, is veel sneller, slaat meestal rijtriggers over en reset vaak identiteitstellers.
Kan TRUNCATE worden teruggedraaid?
In PostgreSQL en SQL Server wel, binnen een transactie. In MySQL en Oracle wordt het impliciet vastgelegd, dus het kan niet worden teruggedraaid.
Reset DELETE de waarde voor automatisch verhogen?
Nee. Na een DELETE gaan nieuwe rijen verder vanaf de vorige teller. In onze SQLite-test was de volgende ID 5 na het verwijderen van alle rijen.
Ondersteunt SQLite TRUNCATE?
Nee. Gebruik de DELETE FROM-tabel zonder WHERE-clausule. SQLite optimaliseert dit wanneer de tabel geen triggers heeft.
Wat verwijdert DROP TABLE?
De gegevens, tabeldefinitie, indexen, triggers en beperkingen. Weergaven en externe sleutels die afhankelijk zijn van de tabel kunnen de drop verbreken of blokkeren.
Blijf leren
Hulp nodig met testen, WordPress of SEO?
We helpen teams betere software te leveren en hun sites te laten groeien. Vertel ons waar u mee bezig bent en wij stellen een duidelijke volgende stap voor.
Meer handleidingen over testen, AI en moderne ontwikkeling
Genoten van dit artikel? Kies een onderwerp en ga direct naar onze nieuwste tutorials.
AI-hallucinaties uitgelegd: waarom taalmodellen dingen verzinnen en hoe ze te verminderen
AI-hallucinaties uitgelegd: wat ze zijn, waarom taalmodellen ze produceren, veelvoorkomende typen, hoe je ze kunt verminderen met aarding en aanwijz…
Lees artikel →DevOpsOmgevingsvariabelen uitgelegd: .env-bestanden, geheimen en configuratie goed gedaan
Omgevingsvariabelen uitgelegd met Python-voorbeelden die we hebben uitgevoerd: ze lezen en instellen, waarom elke waarde een string is, .env-bestand…
Lees artikel →SoftwareontwikkelingAPI-snelheidsbeperking uitgelegd: algoritmen, headers en afhandeling van 429-fouten
API-snelheidsbeperking uitgelegd met een simulatie die we hebben uitgevoerd: token-bucket, vast venster, schuifvenster, 429 reacties, headers van sn…
Lees artikel →TestautomatiseringSpotten in Python: unittest.mock, patch en de fouten die tests doen liegen
Spotten in Python met unittest.mock, getest: Mock en return_value, side_effect, patchen waar een naam wordt gebruikt, spec en autospec, spotdatums e…
Lees artikel →SoftwaretestenCodedekking uitgelegd: lijn versus filiaaldekking en wat 100% werkelijk betekent
Codedekking uitgelegd met een echte dekking.py-run: dekking van lijnen, vertakkingen en condities, een rapport lezen, waarom 100% dekking nog steeds…
Lees artikel →Databases & SQLDELETE versus TRUNCATE versus DROP in SQL: verschillen, terugdraaien en wanneer elk te gebruiken
DELETE versus TRUNCATE versus DROP uitgelegd met geteste SQL: wat elk verwijdert, terugdraaien, triggers, identiteitsreset, snelheid en hoe PostgreS…
Lees artikel →Databases & SQLSQL-weergaven uitgelegd: creëer, gebruik en vermijd de valkuilen, met voorbeelden
SQL-weergaven uitgelegd met query's die we hebben uitgevoerd: een weergave maken, live resultaten, kolommen verbergen, prestaties, bijwerkbare en ge…
Lees artikel →SoftwareontwikkelingTypeScript-interface versus type: echte verschillen, getest met de compiler
TypeScript-interface versus type, gecontroleerd met de echte compiler: wat beide kunnen doen, wat slechts één kan doen, samenvoegen van declaraties,…
Lees artikel →SoftwareontwikkelingPython *args en **kwargs uitgelegd: flexibele functies met duidelijke voorbeelden
Python *args en **kwargs uitgelegd met code die we hebben uitgevoerd: in- en uitpakken, parametervolgorde, argumenten die alleen trefwoorden en posi…
Lees artikel →SoftwareontwikkelingPython Lambda-functies: syntaxis, echt gebruik en wanneer u ze niet moet gebruiken
Python lambda-functies uitgelegd met code die we hebben uitgevoerd: syntaxis, sorteren met sleutel, kaart en filter, sluitingen, de laat-bindende va…
Lees artikel →Kunstmatige intelligentieWat zijn AI-agenten? Hoe ze werken, met een eenvoudige agentloop die u kunt uitvoeren
Wat zijn AI-agenten? Een duidelijke gids voor de agentenlus, tools, geheugen en vangrails, met een kleine Python-lus die we hebben uitgevoerd, echte…
Lees artikel →DevOpsMonitoring versus waarneembaarheid: het echte verschil, met logboeken, statistieken en sporen
Monitoring versus waarneembaarheid uitgelegd: bekende en onbekende fouten, logboeken, statistieken en sporen, een walkthrough voor afrekenincidenten…
Lees artikel →DevOpsDocker-volumes versus bindingsmounts: bewaar containergegevens op de juiste manier
Docker-volumes versus bind-mounts uitgelegd: waarom containergegevens verdwijnen, benoemde volumes, bind-mounts, tmpfs, Compose-voorbeelden, back-up…
Lees artikel →TestautomatiseringTDD versus BDD: belangrijkste verschillen, één functie die op beide manieren is gebouwd en wanneer deze moet worden gebruikt
TDD versus BDD uitgelegd met één kortingsfunctie die in beide richtingen is gebouwd: rood-groen-refactor met code die we hebben uitgevoerd, gegeven-…
Lees artikel →SoftwareontwikkelingGit merge vs rebase: verschillen, voorbeelden en wanneer je wat gebruikt
Git merge vs rebase uitgelegd met echte logoutput, een vergelijkingstabel, de gouden regel van rebase en een veilige teamwerkwijze.
Lees artikel →SoftwareontwikkelingPython list comprehension: syntaxis, voorbeelden en wanneer je het vermijdt
Python list comprehension uitgelegd: syntaxis, filteren, if-else, geneste lussen, gemeten tijden en wanneer een gewone for-lus beter is.
Lees artikel →Databases & SQLSQL JOIN uitgelegd met voorbeelden (Inner, Left, Right, Full)
Begrijp SQL joins stap voor stap met voorbeeldtabellen en queries: INNER, LEFT, RIGHT, FULL, CROSS en SELF, plus veelgemaakte fouten en prestatietips.
Lees artikel →