DELETE vs. TRUNCATE vs. DROP in SQL: Unterschiede, Rollback und Verwendungszweck

  1. Startseite
  2. Blog
  3. Datenbanken und SQL

Datenbanken und SQL

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.

8 Min. Lesezeit
DELETE vs. TRUNCATE vs. DROP in SQL: Unterschiede, Rollback und wann jeweils zu verwenden ist

Das Wichtigste

  • 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 IDENTITY hinzu.
  • 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 CASCADE verwenden. 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

  1. Bestätigen Sie, mit welcher Datenbank und Umgebung Sie verbunden sind.
  2. Führen Sie zuerst die WHERE-Klausel als SELECT aus.
  3. Schließen Sie die Änderung in eine Transaktion ein, sofern Ihre Datenbank sie unterstützt.
  4. Halten Sie vor TRUNCATE oder DROP in der Produktion ein aktuelles, getestetes Backup bereit.
  5. Fügen Sie DROP-Anweisungen in überprüfte Migrationsskripts ein, niemals in Ad-hoc-Konsolen.
  6. Ü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

Arbeiten Sie mit Stack Quora

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.

Lesen Sie weiter

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.

Künstliche Intelligenz

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

Erklä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 →
Softwareentwicklung

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

Spott 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 →
Softwaretests

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

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

Erklä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 →
Softwareentwicklung

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

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

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

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

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

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

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

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

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