DELETE versus TRUNCATE versus DROP in SQL: verschillen, terugdraaien en wanneer elk te gebruiken

  1. Home
  2. Blog
  3. Databases en SQL

Databases en SQL

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.

8 min leestijd
DELETE versus TRUNCATE versus DROP in SQL: verschillen, terugdraaien en wanneer elk te gebruiken

Belangrijkste punten

  • 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 IDENTITY toe.
  • 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 CASCADE gebruikt. 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

  1. Bevestig met welke database en omgeving u bent verbonden.
  2. Voer eerst de WHERE-clausule uit als SELECT.
  3. Verpak de wijziging in een transactie waar uw database dit ondersteunt.
  4. Zorg voor een recente, geteste back-up voordat TRUNCATE of DROP in productie gaat.
  5. Plaats DROP-instructies in beoordeelde migratiescripts, nooit in ad-hocconsoles.
  6. 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

Werk met Stack Quora

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.

Blijf lezen

Meer handleidingen over testen, AI en moderne ontwikkeling

Genoten van dit artikel? Kies een onderwerp en ga direct naar onze nieuwste tutorials.

Kunstmatige intelligentie

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 →
DevOps

Omgevingsvariabelen 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 →
Softwareontwikkeling

API-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 →
Testautomatisering

Spotten 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 →
Softwaretesten

Codedekking 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 & SQL

DELETE 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 & SQL

SQL-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 →
Softwareontwikkeling

TypeScript-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 →
Softwareontwikkeling

Python *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 →
Softwareontwikkeling

Python 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 intelligentie

Wat 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 →
DevOps

Monitoring 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 →
DevOps

Docker-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 →
Testautomatisering

TDD 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 →
Softwareontwikkeling

Git 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 →
Softwareontwikkeling

Python 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 & SQL

SQL 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 →