Ich habe eine MySQL-Tabelle mit einem Primärschlüsselfeld, auf dem AUTO_INCREMENT aktiviert ist. Nachdem ich andere Beiträge hier gelesen habe, habe ich Leute mit dem gleichen Problem und mit unterschiedlichen Antworten bemerkt. Einige empfehlen, diese Funktion nicht zu verwenden, andere geben an, dass sie nicht "repariert" werden kann.
Ich habe:
table: course
fields: courseID, courseName
Beispiel: Anzahl der Datensätze in der Tabelle: 18. Wenn ich die Datensätze 16, 17 und 18 lösche, würde ich erwarten, dass der nächste eingegebene Datensatz die Kurs-ID 16 hat, jedoch 19, da die zuletzt eingegebene Kurs-ID 18 war.
Meine SQL-Kenntnisse sind nicht erstaunlich, aber gibt es trotzdem eine Möglichkeit, diese Anzahl mit einer Abfrage (oder einer Einstellung in der phpMyAdmin-Oberfläche) zu aktualisieren oder zu aktualisieren?
Diese Tabelle bezieht sich auf andere in einer Datenbank.
Angesichts aller Ratschläge habe ich beschlossen, dieses „Problem“ zu ignorieren. Ich werde einfach Datensätze löschen und hinzufügen, während das automatische Inkrement seinen Job erledigt. Ich denke, es spielt keine Rolle, wie die Nummer lautet, da sie nur als eindeutige Kennung verwendet wird und keine (wie oben erwähnte) Geschäftsbedeutung hat .
Für diejenigen, die ich möglicherweise mit meinem ursprünglichen Beitrag verwechselt habe: Ich möchte dieses Feld nicht verwenden, um zu wissen, wie viele Datensätze ich habe. Ich wollte nur, dass die Datenbank ordentlich aussieht und ein bisschen konsistenter ist.
quelle
ENTITY
Tisch und einenENTITY_LOG
Tisch. Jedes Mal, wenn ich etwas in dieENTITY
Tabelle einfüge, aktualisiere oder lösche , protokolliere ich diese AktivitätENTITY_LOG
zusammen mit der Aktivität der Entität in der TabelleId
. Kürzlich hat ein Benutzer eine Reihe von Einträgen in derENTITY
Tabelle gelöscht . und entsprechende Protokolleinträge wurden in der Protokolltabelle vorgenommen. Als heute ein anderer Benutzer versuchte, einen neuen Eintrag in dieENTITY
Tabelle aufzunehmen, war der generierte EintragId
derselbe wie eine zuvor gelöschte Entität! Ich benutze JdbcTemplate und InnoDB.Antworten:
Was Sie versuchen, klingt gefährlich, da dies nicht die beabsichtigte Verwendung ist
AUTO_INCREMENT
.Wenn Sie wirklich den niedrigsten nicht verwendeten Schlüsselwert finden möchten, verwenden Sie ihn überhaupt nicht
AUTO_INCREMENT
und verwalten Sie Ihre Schlüssel manuell. Dies ist jedoch KEINE empfohlene Vorgehensweise.Machen Sie einen Schritt zurück und fragen Sie: " Warum müssen Sie Schlüsselwerte recyceln? " Stellen Sie nicht signierte
INT
(oderBIGINT
) nicht genügend Schlüssel zur Verfügung?Werden Sie
18,446,744,073,709,551,615
im Laufe der Lebensdauer Ihrer Anwendung wirklich mehr als nur eindeutige Datensätze haben?quelle
ALTER TABLE foo AUTO_INCREMENT=1
Wenn Sie die neuesten Einträge gelöscht haben, sollte dies festlegen, dass der nächstniedrigere verfügbare verwendet wird. Solange in noch keine 19 vorhanden ist, wird durch Löschen von 16-18 die automatische Inkrementierung auf 16 zurückgesetzt.
EDIT: Ich habe das bisschen über phpmyadmin verpasst. Sie können es auch dort einstellen. Gehen Sie zum Tabellenbildschirm und klicken Sie auf die Registerkarte Vorgänge. Dort gibt es ein
AUTOINCREMENT
Feld, das Sie manuell einstellen können.quelle
Primäre Autoincrement-Schlüssel in der Datenbank werden verwendet, um eine bestimmte Zeile eindeutig zu identifizieren, und sollten keine geschäftliche Bedeutung erhalten. Lassen Sie also den Primärschlüssel unverändert und fügen Sie eine weitere Spalte hinzu, die beispielsweise aufgerufen wird
courseOrder
. Wenn Sie dann einen Datensatz aus der Datenbank löschen, möchten Sie möglicherweise eine zusätzliche UPDATE-Anweisung senden, um diecourseOrder
Spalte aller Zeilen zu dekrementieren , diecourseOrder
größer sind als die, die Sie gerade löschen.Als Randnotiz sollten Sie niemals den Wert eines Primärschlüssels in einer relationalen Datenbank ändern, da es andere Tabellen geben kann, die ihn als Fremdschlüssel referenzieren, und wenn Sie ihn ändern, kann dies gegen referenzielle Einschränkungen verstoßen.
quelle
count
Aggregatfunktion erledigt den Job.Versuchen :
Dadurch wird der automatisch inkrementierte Wert zurückgesetzt und anschließend jede Zeile gezählt, während ein neuer Wert dafür erstellt wird.
Beispiel: vorher
In der Tabelle wird also das Array angezeigt: 1,2,4,5
Beispiel: AFTER (wenn Sie diesen Befehl verwenden, erhalten Sie)
Keine Spur des gelöschten Wertes, und der Rest des inkrementierten Werts wird mit dieser neuen Zählung fortgesetzt.
ABER
quelle
Sie sollten sich nicht auf die AUTO_INCREMENT-ID verlassen, um zu erfahren, wie viele Datensätze Sie in der Tabelle haben. Sie sollten verwenden
SELECT COUNT(*) FROM course
. IDs dienen dazu, den Kurs eindeutig zu identifizieren, und können als Referenzen in anderen Tabellen verwendet werden. Sie sollten daher keine IDs wiederholen und nicht versuchen, das Feld für die automatische Inkrementierung zurückzusetzen.quelle
Sie können die IDs wie folgt auswählen:
set @rank = 0; select id, @rank:=@rank+1 from tbl order by id
Das Ergebnis ist eine Liste der IDs und ihrer Positionen in der Sequenz.
Sie können die IDs auch folgendermaßen zurücksetzen:
set @rank = 0; update tbl a join (select id, @rank:=@rank+1 as rank from tbl order by id) b on a.id = b.id set a.id = b.rank;
Sie können auch einfach die erste nicht verwendete ID wie folgt ausdrucken:
select min(id) as next_id from ((select a.id from (select 1 as id) a left join tbl b on a.id = b.id where b.id is null) union (select min(a.id) + 1 as id from tbl a left join tbl b on a.id+1 = b.id where b.id is null)) c;
Nach jeder Einfügung können Sie das auto_increment zurücksetzen:
alter table tbl auto_increment = 16
oder setzen Sie den ID-Wert beim Einfügen explizit:
insert into tbl values (16, 'something');
In der Regel ist dies nicht erforderlich, und Sie haben
count(*)
die Möglichkeit, eine Rangfolge in Ihren Ergebnismengen zu erstellen. Ein typisches Ranking könnte sein:set @rank = 0; select a.name, a.amount, b.rank from cust a, (select amount, @rank:=@rank+1 as rank from cust order by amount desc) b where a.amount = b.amount
Kunden nach ausgegebenem Betrag geordnet.
quelle
Ich bin hierher gekommen, um eine Antwort auf die Titelfrage zu suchen,
"MySQL - Auto Increment after delete"
aber ich konnte nur in den Fragen eine Antwort darauf findenMit etwas wie:
DELETE FROM table; ALTER TABLE table AUTO_INCREMENT = 1;
Beachten Sie, dass Darin Dimitrovs Antwort sehr gut erklärt
AUTO_INCREMENT
und verwendet wird. Schauen Sie dort nach, bevor Sie etwas tun, das Sie vielleicht bereuen.PS: Die Frage selbst ist mehr
"Why you need to recycle key values?"
und Dolphs Antwort deckt das ab.quelle
Ich kann mir viele Szenarien vorstellen, in denen Sie dies möglicherweise tun müssen, insbesondere während eines Migrations- oder Entwicklungsprozesses. Zum Beispiel musste ich gerade eine neue Tabelle erstellen, indem ich zwei vorhandene Tabellen miteinander verband (als Teil eines komplexen Einrichtungsprozesses), und dann musste ich nach dem Ereignis einen Primärschlüssel hinzufügen. Sie können die vorhandene Primärschlüsselspalte löschen und dies dann tun.
ALTER TABLE my_table ADD `ID` INT NOT NULL AUTO_INCREMENT FIRST, ADD PRIMARY KEY (`ID`);
Für ein Live-System ist dies keine gute Idee, insbesondere wenn andere Tabellen mit Fremdschlüsseln darauf verweisen.
quelle
Ich habe eine sehr einfache, aber knifflige Methode.
Während Sie eine Zeile löschen, können Sie die IDs in einer anderen temporären Tabelle beibehalten. Wenn Sie danach neue Daten in die Haupttabelle einfügen, können Sie IDs suchen und aus der temporären Tabelle auswählen. Verwenden Sie hier also eine Überprüfung. Wenn die temporäre Tabelle keine IDs hat, berechnen Sie die maximale ID in der Haupttabelle und legen Sie die neue ID wie folgt fest :
new_ID = old_max_ID+1
.Hinweis: Sie können die automatische Inkrementierungsfunktion hier nicht verwenden.
quelle
Was Sie versuchen zu tun, ist sehr gefährlich. Überlegen Sie genau. Es gibt einen sehr guten Grund für das Standardverhalten der automatischen Inkrementierung.
Bedenken Sie:
Ein Datensatz wird in einer Tabelle gelöscht, die eine Beziehung zu einer anderen Tabelle hat. Der entsprechende Datensatz in der zweiten Tabelle kann aus Prüfungsgründen nicht gelöscht werden. Dieser Datensatz wird ab der ersten Tabelle verwaist. Wenn ein neuer Datensatz in die erste Tabelle eingefügt wird und ein sequentieller Primärschlüssel verwendet wird, ist dieser Datensatz jetzt mit dem Orphan verknüpft. Das ist natürlich schlecht. Durch die Verwendung einer automatisch inkrementierten PK wird immer eine ID garantiert, die noch nie zuvor verwendet wurde. Dies bedeutet, dass Waisen Waisen bleiben, was richtig ist.
quelle
Es gibt tatsächlich eine Möglichkeit, dies zu beheben. Zuerst löschen Sie die Primärschlüsselspalte auto_incremented und fügen sie dann erneut hinzu:
ALTER TABLE table_name DROP column_name; ALTER TABLE table_name ADD column_name int not null auto_increment primary key first;
quelle
Sie können Ihre MySQL-Client-Software / -Skript verwenden, um anzugeben, wo der Primärschlüssel nach dem Löschen der erforderlichen Datensätze beginnen soll.
quelle
Möglicherweise möchten Sie nach dem Löschen einen Trigger erstellen, um den Wert der automatischen Inkrementierung und den ID-Wert aller Zeilen zu aktualisieren, die nicht den gewünschten Angaben entsprechen.
Sie können also mit derselben Tabelle arbeiten und das automatische Inkrement wird automatisch korrigiert, wenn Sie eine Zeile löschen, die der Trigger repariert.
quelle
Es ist definitiv nicht zu empfehlen. Wenn Sie eine große Datenbank mit mehreren Tabellen haben, haben Sie möglicherweise eine Benutzer-ID als ID in Tabelle 2 gespeichert. Wenn Sie Tabelle 1 neu anordnen, wird die beabsichtigte Benutzer-ID wahrscheinlich nicht die beabsichtigte ID für Tabelle 2 sein.
quelle
MYSQL Query Auto Increment Solution. Es funktioniert perfekt, wenn Sie während der Testphase der Software viele Datensätze eingefügt haben. Jetzt möchten Sie Ihre Anwendung live auf Ihrem Client starten und die automatische Inkrementierung ab 1 starten.
Um unerwünschte Probleme zu vermeiden, aus Sicherheitsgründen zuerst
.sql
Datei exportieren .Befolgen Sie dann die folgenden Schritte:
Schritt 1) Erstellen Sie zuerst die Kopie einer vorhandenen Tabelle MySQL Command, um eine Kopie zu erstellen:
CREATE TABLE new_Table_Name SELECT * FROM existing_Table_Name;
Die genaue Kopie einer Tabelle wird mit allen Zeilen außer Einschränkungen erstellt.
Einschränkungen wie Auto Increment und Primary Key werden nicht kopiert
new_Table_name
Schritt 2) Alle Zeilen löschen Wenn in der Testphase keine Daten eingefügt wurden und dies nicht sinnvoll ist. Wenn Daten wichtig sind, fahren Sie direkt mit Schritt 3 fort.
DELETE from new_Table_Name;
Schritt 3) Um Einschränkungen hinzuzufügen, wechseln Sie zur Struktur einer Tabelle
None
.quelle
if($id == 1){ // deleting first row mysqli_query($db,"UPDATE employees SET id=id-1 WHERE id>1"); } else if($id>1 && $id<$num){ // deleting middle row mysqli_query($db,"UPDATE employees SET id=id-1 WHERE id>$id"); } else if($id == $num){ // deleting last row mysqli_query($db,"ALTER TABLE employees AUTO_INCREMENT = $num"); } else{ echo "ERROR"; } mysqli_query($db,"ALTER TABLE employees AUTO_INCREMENT = $num");
quelle
Hier ist eine Funktion, die Ihr Problem behebt
public static void fixID(Connection conn, String table) { try { Statement myStmt = conn.createStatement(); ResultSet myRs; int i = 1, id = 1, n = 0; boolean b; String sql; myRs = myStmt.executeQuery("select max(id) from " + table); if (myRs.next()) { n = myRs.getInt(1); } while (i <= n) { b = false; myRs = null; while (!b) { myRs = myStmt.executeQuery("select id from " + table + " where id=" + id); if (!myRs.next()) { id++; } else { b = true; } } sql = "UPDATE " + table + " set id =" + i + " WHERE id=" + id; myStmt.execute(sql); i++; id++; } } catch (SQLException e) { e.printStackTrace(); } }
quelle