MySQL Löschen Sie alle Zeilen aus der Tabelle und setzen Sie die ID auf Null zurück

182

Ich muss alle Zeilen aus einer Tabelle löschen, aber wenn ich eine neue Zeile hinzufüge, möchte ich, dass die Primärschlüssel-ID, die ein automatisches Inkrement aufweist, erneut von 0 bzw. 1 beginnt.

marek_lani
quelle

Antworten:

303

Nicht löschen, abschneiden:

Truncate table XXX

Der Tabellenhandler merkt sich nicht den zuletzt verwendeten AUTO_INCREMENT-Wert, sondern beginnt von vorne zu zählen. Dies gilt auch für MyISAM und InnoDB, die normalerweise keine Sequenzwerte wiederverwenden.

Quelle .

Francois
quelle
20
Das Abschneiden funktioniert gut mit nicht eingeschränkten Tabellen. Wenn Ihre Tabelle jedoch eine Fremdschlüsseleinschränkung aufweist, können Sie die Delete-Methode verwenden. Siehe diesen Beitrag, wenn Sie FK-Einschränkungen haben: Fremdschlüssel-
Julian Soro
1
Denken Sie daran, dass abgeschnittene Tabelle nicht zurückrollen wird
Penny Chan
83

Wenn Sie nicht verwenden können TRUNCATE(z. B. aufgrund von Fremdschlüsseleinschränkungen), können Sie nach dem Löschen aller Zeilen eine Änderungstabelle verwenden, um das auto_increment neu zu starten:

ALTER TABLE mytable AUTO_INCREMENT = 1
ein Pferd ohne Name
quelle
3
@NBhargav Da Sie möglicherweise anstelle von MyISAM die InnoDB-Engine für Ihre Tabelle verwenden, unterstützt das erste das Zurücksetzen des Index nicht.
Gustavo Rubio
wie man alle Zeilen löscht, bevor man den Wert für
auto_increment
@ KasunSiyambalapitiya DELETE FROM tablename;(aber das wird nicht gut funktionieren, wenn es FK-Einschränkungen gibt - siehe stackoverflow.com/a/5452798/507761 )
Matthew Read
17

Wenn die Tabelle Fremdschlüssel enthält, verwende ich immer den folgenden Code:

SET FOREIGN_KEY_CHECKS = 0; -- disable a foreign keys check
SET AUTOCOMMIT = 0; -- disable autocommit
START TRANSACTION; -- begin transaction

/*
DELETE FROM table_name;
ALTER TABLE table_name AUTO_INCREMENT = 1;
-- or
TRUNCATE table_name;
-- or
DROP TABLE table_name;
CREATE TABLE table_name ( ... );
*/

SET FOREIGN_KEY_CHECKS = 1; -- enable a foreign keys check
COMMIT;  -- make a commit
SET AUTOCOMMIT = 1 ;

Der Unterschied liegt jedoch in der Ausführungszeit. Schau oben auf Sorins Antwort.

schwarz
quelle
2
Dies ist eine gute Möglichkeit, verwaiste Daten in einer Tabelle zu haben, die Fremdschlüssel für die Tabelle enthält, die Sie löschen. Das Aktivieren der Fremdschlüsselprüfungen nachträglich führt nicht dazu, dass MySQL diese Fremdschlüssel meines Wissens erneut validiert. Dadurch erhalten Sie Zeilen, die Daten enthalten, die in der Referenztabelle nicht vorhanden sind . Möglicherweise haben Sie auch gar keine Fremdschlüssel auf Ihrem Tisch.
Cimmanon
8

Ein interessanter Fakt.

Ich war mir sicher, dass TRUNCATEdie Leistung immer besser sein wird, aber in meinem Fall dauerte es für eine Datenbank mit ungefähr 30 Tabellen mit Fremdschlüsseln, die nur mit wenigen Zeilen gefüllt waren, ungefähr 12 Sekunden für TRUNCATEalle Tabellen, im Gegensatz zu nur ein paar hundert Millisekunden für DELETEdie Reihen. Durch Einstellen des automatischen Inkrements wird insgesamt etwa eine Sekunde hinzugefügt, aber es ist immer noch viel besser.

Daher würde ich vorschlagen, beide zu versuchen und herauszufinden, welche für Ihren Fall schneller funktioniert.

Sorin
quelle
2

Wenn Sie verwenden möchten, verwenden Sie Folgendes truncate:

SET FOREIGN_KEY_CHECKS = 0; 
TRUNCATE table $table_name; 
SET FOREIGN_KEY_CHECKS = 1;
david2020
quelle