DELETE vs. TRUNCATE vs. DROP: Unterschiede, Rollback und wann jeweils zu verwenden ist
Alle drei Befehle entfernen etwas, aber sie entfernen unterschiedliche Dinge auf unterschiedliche Weise. Hier erfahren Sie, was jeder tut, was Sie rückgängig machen können und wie sich die Regeln zwischen den Datenbanken ändern.
- DELETE entfernt Zeilen, optional gefiltert mit WHERE. Der Tisch bleibt.
- TRUNCATE entfernt alle Zeilen schnell. Die Tabellenstruktur bleibt erhalten.
- DROP entfernt die gesamte Tabelle: Daten, Struktur, Indizes und Trigger.
- Rollback, Trigger und Identitätszurücksetzung verhalten sich in jeder Datenbank unterschiedlich, also überprüfen Sie Ihre.
Ein Tester möchte eine Staging-Tabelle vor einem neuen Testlauf löschen. Sollte es DELETE, TRUNCATE oder DROP sein? Die falsche Wahl kann eine langsame Arbeit, einen fehlenden Tisch oder, in der Produktion, einen sehr schlechten Nachmittag bedeuten.
Wir haben die DELETE- und DROP-Beispiele unten in SQLite 3.50 ausgeführt und die Ausgaben stammen aus dieser Ausführung. SQLite verfügt über keinen TRUNCATE-Befehl, daher basieren die TRUNCATE-Hinweise auf der offiziellen PostgreSQL-, MySQL- und SQL Server-Dokumentation und nicht auf unserem eigenen Test.
Die kurze Antwort
- Müssen einige Zeilen entfernt werden? Verwenden Sie
DELETE ... WHERE. - Müssen Sie einen Tisch leeren, ihn aber behalten? Verwenden Sie
TRUNCATE, wo es unterstützt wird. - Muss der Tisch endgültig verschwunden sein? Verwenden Sie
DROP TABLE.
LÖSCHEN: Zeilen entfernen
DELETE ist ein Datenänderungsbefehl (DML). Es entfernt Zeilen einzeln, löst Trigger auf Zeilenebene aus und kann gefiltert werden. Wir haben eine kleine Tabelle mit einem Audit-Trigger eingerichtet:
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'
Nur die passende Zeile wurde gelöscht und vom Auslöser aufgezeichnet. Beim Ausführen von DELETE FROM logs ohne WHERE-Klausel wurden die anderen drei Zeilen entfernt, und die Prüftabelle enthielt dann vier Einträge, einen pro gelöschter Zeile.
DELETE setzt die automatisch inkrementierenden Zähler nicht zurück. Nach dem Leeren der Tabelle erhielt unsere nächste Einfügung id 5, nicht 1. In SQLite liegt das an AUTOINCREMENT. MySQL InnoDB- und SQL Server-Identitätsspalten werden auch nach einem DELETE-Vorgang dort fortgesetzt, wo sie waren.
Tipp: Führen Sie vor jedem DELETE-Vorgang mit einer WHERE-Klausel zuerst dieselbe Klausel wie eine SELECT COUNT(*) aus. Wenn Sie die Zählung überrascht, hören Sie auf. Lesen Sie unseren Leitfaden zu SQL-NULL-Werten für die Traps, die NULL in einer WHERE-Klausel erstellt.
TRUNCATE: Leeren Sie die Tabelle
TRUNCATE TABLE logs; entfernt jede Zeile auf einmal. Es kann keine WHERE-Klausel akzeptiert werden. Anstatt Zeilen einzeln zu löschen, gibt die Datenbank normalerweise die Datenseiten der Tabelle frei, weshalb dies bei großen Tabellen viel schneller ist.
Als wir es in SQLite ausgeführt haben, bekamen wir einen Syntaxfehler, da SQLite nicht über den folgenden Befehl verfügt:
TRUNCATE TABLE logs;
-- near "TRUNCATE": syntax error
Verwenden Sie in SQLite DELETE FROM logs; ohne WHERE-Klausel. Die Dokumentation von SQLite beschreibt eine „Truncate-Optimierung“, die dies schnell macht, wenn die Tabelle keine Trigger hat. Unsere Tabelle hatte einen Auslöser, sodass der Löschvorgang Zeile für Zeile ausgeführt und für jede Zeile ausgelöst wurde.
In Datenbanken, die TRUNCATE unterstützen, laut Dokumentation:
- Normalerweise werden keine DELETE-Trigger auf Zeilenebene ausgelöst.
- Es setzt normalerweise Identitäts- oder Auto-Inkrement-Zähler zurück, beispielsweise in MySQL und SQL Server. In PostgreSQL fügen Sie
RESTART IDENTITYhinzu. - In den meisten Systemen sind stärkere Berechtigungen als DELETE erforderlich.
DROP: Entfernen Sie die Tabelle selbst
DROP TABLE ist ein Schema-Befehl (DDL). Es entfernt die Daten, die Tabellendefinition, ihre Indizes, Trigger und Einschränkungen. Auch alles, was auf die Tabelle verweist, wie Ansichten oder Fremdschlüssel, ist betroffen.
DROP TABLE logs;
SELECT * FROM logs;
-- no such table: logs
DROP TABLE IF EXISTS logs; -- no error, even though it is gone
IF EXISTS ist praktisch in Setup-Skripten, die möglicherweise mehr als einmal ausgeführt werden. Ansichten auf einer gelöschten Tabelle können kaputt gehen, wie wir in Erklärte SQL-Ansichten gezeigt haben.
Vergleichstabelle
| Funktion | LÖSCHEN | ABSCHNEIDEN | TROPFEN |
|---|---|---|---|
| Entfernt | Einige oder alle Zeilen | Alle Reihen | Tabelle und Zeilen |
| WHERE-Klausel | Ja | Nein | Nein |
| Befehlstyp | DML | DDL (normalerweise) | DDL |
| Streit löst Feuer aus | Ja | Normalerweise nein | Nein |
| Setzt die Identität zurück | Nein | Normalerweise ja | Der Tisch ist weg |
| Geschwindigkeit auf großen Tischen | Langsam | Schnell | Schnell |
| Tisch bleibt übrig | Ja | Ja | Nein |
Kannst du zurückrollen?
Hier wird in vielen Artikeln zu stark vereinfacht. Die ehrliche Antwort ist, dass es von der Datenbank abhängt.
DELETE kann innerhalb einer Transaktion überall zurückgesetzt werden. Wir haben es getestet:
BEGIN;
DELETE FROM logs;
SELECT COUNT(*) FROM logs; -- 0
ROLLBACK;
SELECT COUNT(*) FROM logs; -- 3
DROP wurde auch in SQLite zurückgesetzt, das transaktionales DDL unterstützt:
BEGIN;
DROP TABLE logs;
ROLLBACK;
SELECT COUNT(*) FROM logs; -- 1 (the table is back)
Für TRUNCATE und DROP in anderen Datenbanken laut deren Dokumentation:
| Datenbank | TRUNCATE/DROP in einer Transaktion |
|---|---|
| PostgreSQL | Kann zurückgesetzt werden. DDL ist transaktional. |
| SQL-Server | Kann innerhalb einer expliziten Transaktion zurückgesetzt werden. |
| MySQL | Verursacht ein implizites Commit und kann daher nicht zurückgesetzt werden. |
| Orakel | Wird implizit festgeschrieben. DROP kann möglicherweise aus dem Papierkorb wiederhergestellt werden. |
Daher ist „TRUNCATE kann nie zurückgesetzt werden“ für PostgreSQL und SQL Server falsch, und „es kann immer zurückgesetzt werden“ ist für MySQL falsch. Außerhalb einer Transaktion kann keine davon ohne Backup rückgängig gemacht werden.
Warum TRUNCATE schnell ist
DELETE protokolliert jede entfernte Zeile, sodass die Änderung rückgängig gemacht und repliziert werden kann, löst Trigger aus und überprüft Einschränkungen Zeile für Zeile. Bei einer Tabelle mit Millionen von Zeilen erzeugt das viel Arbeit und Protokollvolumen. TRUNCATE gibt den Speicher im Allgemeinen in einem Vorgang frei und protokolliert deutlich weniger. Um eine große Teilmenge und nicht alles zu entfernen, löschen Sie stapelweise, um lange Sperren zu vermeiden. Wir decken Sperr- und Abfragekosten bei der SQL-Abfrageoptimierung ab.
Fremdschlüssel und Berechtigungen
- Fremdschlüssel. SQL Server weigert sich, eine Tabelle abzuschneiden, auf die durch einen Fremdschlüssel verwiesen wird. PostgreSQL erfordert, dass Sie auch die referenzierenden Tabellen kürzen oder
CASCADEverwenden. Stattdessen prüft ein DELETE-Befehl jede Zeile anhand der Einschränkungen. - Berechtigungen. DELETE benötigt Löschrechte. TRUNCATE benötigt oft ALTER oder ein dediziertes TRUNCATE-Recht, und DROP benötigt Besitz oder ALTER für das Schema.
- Replikation und Prüfung. Wenn andere Systeme auf Änderungsprotokolle oder Trigger auf Zeilenebene angewiesen sind, kann TRUNCATE diese überspringen. Erkundigen Sie sich zuerst bei dem Besitzer dieser Systeme.
Welches soll ich verwenden?
| Situation | Benutzen |
|---|---|
| Entfernen Sie die stornierten Bestellungen eines Kunden | LÖSCHEN mit WHERE |
| Setzen Sie vor jedem Testlauf eine Staging-Tabelle zurück | TRUNCATE (oder DELETE in SQLite) |
| Sorgen Sie dafür, dass Audit-Trigger funktionieren | LÖSCHEN |
| Entfernen Sie eine Tabelle, die nicht mehr im Design enthalten ist | DROP in einer überprüften Migration |
| Löschen Sie Millionen alter Zeilen, behalten Sie aber die neuesten Zeilen bei | LÖSCHEN Sie stapelweise oder partitionieren Sie alte Partitionen und löschen Sie sie |
Für Testdaten ist TRUNCATE beliebt, da es IDs zurücksetzt, wodurch Tests wiederholbar werden. Das Einschließen jedes Tests in eine Transaktion, die zurückgesetzt wird, ist eine weitere Option, die in SQL-Transaktionen und ACID erläutert wird.
Sicherheitscheckliste
- Bestätigen Sie, mit welcher Datenbank und Umgebung Sie verbunden sind.
- Führen Sie zuerst die WHERE-Klausel als SELECT aus.
- Schließen Sie die Änderung in eine Transaktion ein, sofern Ihre Datenbank sie unterstützt.
- Halten Sie vor TRUNCATE oder DROP in der Produktion ein aktuelles, getestetes Backup bereit.
- Fügen Sie DROP-Anweisungen in überprüfte Migrationsskripts ein, niemals in Ad-hoc-Konsolen.
- Überprüfen Sie, was von einer Tabelle abhängt, z. B. Ansichten, Fremdschlüssel und Berichte, bevor Sie sie löschen.
Große Datenmengen sicher löschen
Das Entfernen von Millionen Zeilen mit einem DELETE-Vorgang kann die Tabelle für lange Zeit sperren, das Transaktionsprotokoll füllen und die Replikation verlangsamen. Ein gängiges Muster besteht darin, in kleinen Mengen zu löschen und zu wiederholen, bis nichts mehr übrig ist:
-- 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);
Führen Sie die Anweisung in einer Schleife mit einer kurzen Pause zwischen den Stapeln aus, bis keine Zeilen gemeldet werden. Jeder Stapel ist eine kleine Transaktion, daher sind die Sperren kurz und andere Abfragen werden weiter ausgeführt. Ein Index auf der Filterspalte, hier created_at, sorgt dafür, dass jeder Stapel schnell bleibt.
Für Daten, die mit dem Datum wachsen, wie Protokolle und Ereignisse, ist die Tabellenpartitionierung sogar noch besser. Jeder Monat befindet sich in einer eigenen Partition, und das Entfernen alter Daten wird zu einem schnellen Vorgang, bei dem eine Partition gelöscht oder gekürzt wird, anstatt Zeilen einzeln zu löschen.
Soft-Löschungen
Viele Anwendungen löschen Geschäftsunterlagen nie physisch. Sie fügen eine Spalte wie deleted_at hinzu und legen sie stattdessen fest, und Abfragen filtern dann nach deleted_at IS NULL. Vorläufige Löschungen erleichtern die Wiederherstellung und bewahren den Verlauf für Prüfungen auf, aber jede Abfrage muss sich den Filter merken, was für eine Ansicht eine gute Aufgabe ist. Eindeutige Einschränkungen erfordern ebenfalls Sorgfalt, da eine vorläufig gelöschte Zeile weiterhin ihren Wert behält. Datenschutzgesetze erfordern möglicherweise die tatsächliche Löschung personenbezogener Daten nach einer gewissen Zeit, daher sind vorläufige Löschungen kein Ersatz für eine Aufbewahrungsrichtlinie.
Fazit
DELETE ist das präzise und sorgfältige Werkzeug. TRUNCATE ist die Schaltfläche zum schnellen Zurücksetzen, und DROP entfernt die Tabelle vollständig. Das größte Risiko besteht darin, anzunehmen, dass sich eine Datenbank wie eine andere verhält, insbesondere beim Rollback. Testen Sie den Befehl im Zweifelsfall zunächst an einer Kopie der Tabelle in Ihrer eigenen Datenbank.
Häufige Fragen
Was ist der Hauptunterschied zwischen DELETE und TRUNCATE?
DELETE entfernt Zeilen nacheinander, unterstützt WHERE und löst Trigger aus. TRUNCATE entfernt alle Zeilen auf einmal, ist viel schneller, überspringt normalerweise Zeilentrigger und setzt häufig Identitätszähler zurück.
Kann TRUNCATE zurückgesetzt werden?
In PostgreSQL und SQL Server ja, innerhalb einer Transaktion. In MySQL und Oracle wird es implizit festgeschrieben, sodass kein Rollback möglich ist.
Setzt DELETE den Wert für die automatische Erhöhung zurück?
Nein. Nach einem DELETE werden neue Zeilen vom vorherigen Zähler aus fortgesetzt. In unserem SQLite-Test war die nächste ID 5, nachdem alle Zeilen gelöscht wurden.
Unterstützt SQLite TRUNCATE?
Nein. Verwenden Sie die DELETE FROM-Tabelle ohne WHERE-Klausel. SQLite optimiert dies, wenn die Tabelle keine Trigger hat.
Was entfernt DROP TABLE?
Die Daten, Tabellendefinition, Indizes, Trigger und Einschränkungen. Ansichten und Fremdschlüssel, die von der Tabelle abhängen, können den Drop unterbrechen oder blockieren.
Lerne weiter
Benötigen Sie Hilfe beim Testen, WordPress oder SEO?
Wir helfen Teams, bessere Software zu liefern und ihre Websites zu erweitern. Sagen Sie uns, woran Sie gerade arbeiten, und wir schlagen Ihnen einen klaren nächsten Schritt vor.
Weitere Anleitungen finden Sie unter Tests, KI und moderne Entwicklung
Hat Ihnen dieser Artikel gefallen? Wählen Sie ein Thema und springen Sie direkt in unsere neuesten Tutorials.
KI-Halluzinationen erklärt: Warum Sprachmodelle Dinge erfinden und wie man sie reduziert
KI-Halluzinationen erklärt: Was sie sind, warum Sprachmodelle sie produzieren, gängige Typen, wie man sie mit Erdung und Eingabeaufforderungen reduz…
Artikel lesen →DevOpsErklärte Umgebungsvariablen: .env-Dateien, Geheimnisse und Konfiguration richtig gemacht
Umgebungsvariablen anhand von Python-Beispielen erklärt, die wir ausgeführt haben: Sie lesen und festlegen, warum jeder Wert ein String ist, .env-Da…
Artikel lesen →SoftwareentwicklungAPI-Ratenbegrenzung erklärt: Algorithmen, Header und Behandlung von 429-Fehlern
API-Ratenbegrenzung anhand einer von uns durchgeführten Simulation erklärt: Token-Bucket, festes Fenster, gleitendes Fenster, 429 Antworten, Ratenbe…
Artikel lesen →TestautomatisierungSpott in Python: unittest.mock, Patch und die Fehler, die Tests zum Lügen machen
Mocking in Python mit unittest.mock, getestet: Mock und return_value, side_effect, Patchen, wo ein Name verwendet wird, Spezifikation und Autospec, …
Artikel lesen →SoftwaretestsCode-Abdeckung erklärt: Leitungs- und Zweigstellenabdeckung und was 100 % wirklich bedeutet
Erklärung der Codeabdeckung anhand eines echten Coverage.py-Laufs: Zeilen-, Zweig- und Bedingungsabdeckung, Lesen eines Berichts, warum bei 100 % Ab…
Artikel lesen →Datenbanken & SQLDELETE vs. TRUNCATE vs. DROP in SQL: Unterschiede, Rollback und Verwendungszweck
DELETE vs. TRUNCATE vs. DROP erklärt mit getestetem SQL: was jeweils entfernt wird, Rollback, Trigger, Identitätsrücksetzung, Geschwindigkeit und wi…
Artikel lesen →Datenbanken & SQLErklärte SQL-Ansichten: Erstellen, nutzen und vermeiden Sie Fallstricke mit Beispielen
SQL-Ansichten anhand der von uns ausgeführten Abfragen erklärt: Erstellen einer Ansicht, Live-Ergebnisse, Ausblenden von Spalten, Leistung, aktualis…
Artikel lesen →SoftwareentwicklungTypeScript-Schnittstelle vs. Typ: Echte Unterschiede, getestet mit dem Compiler
TypeScript-Schnittstelle vs. Typ, überprüft mit dem echten Compiler: Was beide können, was nur einer kann, Deklarationszusammenführung, Erweiterunge…
Artikel lesen →SoftwareentwicklungPython *args und **kwargs erklärt: Flexible Funktionen mit klaren Beispielen
Python *args und **kwargs erklärt mit Code, den wir ausgeführt haben: Packen und Entpacken, Parameterreihenfolge, Nur-Schlüsselwort- und Nur-Positio…
Artikel lesen →SoftwareentwicklungPython-Lambda-Funktionen: Syntax, tatsächliche Verwendung und wann man sie nicht verwendet
Python-Lambda-Funktionen erklärt mit Code, den wir ausgeführt haben: Syntax, Sortierung mit Schlüssel, Karte und Filter, Abschlüsse, die Late-Bindin…
Artikel lesen →Künstliche IntelligenzWas sind KI-Agenten? Wie sie funktionieren, mit einer einfachen Agentenschleife, die Sie ausführen können
Was sind KI-Agenten? Eine einfache Anleitung zur Agentenschleife, zu Tools, Speicher und Leitplanken, mit einer kleinen Python-Schleife, die wir aus…
Artikel lesen →DevOpsÜberwachung vs. Beobachtbarkeit: Der wahre Unterschied, mit Protokollen, Metriken und Traces
Überwachung vs. Beobachtbarkeit erklärt: bekannte und unbekannte Fehler, Protokolle, Metriken und Spuren, eine exemplarische Vorgehensweise für Chec…
Artikel lesen →DevOpsDocker-Volumes vs. Bind Mounts: Containerdaten auf die richtige Art und Weise beibehalten
Docker-Volumes vs. Bind-Mounts erklärt: Warum Containerdaten verschwinden, benannte Volumes, Bind-Mounts, tmpfs, Compose-Beispiele, Backups, Berecht…
Artikel lesen →TestautomatisierungTDD vs. BDD: Hauptunterschiede, eine Funktion, die auf beide Arten entwickelt wurde und wann sie jeweils verwendet werden sollte
TDD vs. BDD erklärt mit einer Rabattfunktion, die in beide Richtungen aufgebaut ist: Rot-Grün-Refaktor mit Code, den wir ausgeführt haben, Gegeben-W…
Artikel lesen →SoftwareentwicklungGit merge vs rebase: Unterschiede, Beispiele und wann man was nutzt
Git merge vs rebase erklärt mit echter Log-Ausgabe, einer Vergleichstabelle, der goldenen Regel des Rebase und einem sicheren Team-Workflow.
Artikel lesen →SoftwareentwicklungPython List Comprehension: Syntax, Beispiele und wann man darauf verzichtet
Python List Comprehension erklärt: Syntax, Filter, if-else, verschachtelte Schleifen, gemessene Zeiten und Fälle, in denen eine normale for-Schleife…
Artikel lesen →Datenbanken & SQLSQL Joins erklärt mit Beispielen (Inner, Left, Right, Full)
SQL Joins Schritt für Schritt mit Beispieltabellen und Abfragen verstehen: INNER, LEFT, RIGHT, FULL, CROSS und SELF, plus typische Fehler und Perfor…
Artikel lesen →