Mysql
 sql >> Datenbank >  >> RDS >> Mysql

Wie füllt man die Löcher in Auto-Increment-Feldern aus?

Ich stimme @Aaron Digulla und @Shane N. zu. Die Lücken sind bedeutungslos. Wenn sie es TUN etwas bedeuten, das ist ein fehlerhaftes Datenbankdesign. Punkt.

Davon abgesehen, wenn Sie diese Löcher unbedingt füllen MÜSSEN, UND Wenn Sie mindestens MySQL 3.23 ausführen, können Sie eine TEMPORARY TABLE verwenden, um einen neuen Satz von IDs zu erstellen. Die Idee dabei ist, dass Sie alle Ihre aktuellen IDs der Reihe nach in eine temporäre Tabelle wie folgt einfügen:

CREATE TEMPORARY TABLE NewIDs
(
    NewID INT UNSIGNED AUTO INCREMENT,
    OldID INT UNSIGNED
)

INSERT INTO NewIDs (OldId)
SELECT
    Id
FROM
    OldTable
ORDER BY
    Id ASC

Dadurch erhalten Sie eine Tabelle, die Ihre alte ID einer brandneuen ID zuordnet, die aufgrund der AUTO INCREMENT-Eigenschaft der NewId-Spalte sequenziell sein wird.

Sobald dies erledigt ist, müssen Sie alle anderen Verweise auf die ID in „OldTable“ und alle verwendeten Fremdschlüssel aktualisieren. Dazu müssen Sie wahrscheinlich alle Fremdschlüsseleinschränkungen, die Sie haben, löschen, alle Verweise in Tabellen von OldId auf NewId aktualisieren und dann Ihre Fremdschlüsseleinschränkungen neu einrichten.

Ich würde jedoch argumentieren, dass Sie IRGENDWELCHES tun sollten und verstehen Sie einfach, dass Ihr Id-Feld nur zum Verweisen auf einen Datensatz dient und NICHT sollte eine bestimmte Relevanz haben.

UPDATE:Hinzufügen eines Beispiels zum Aktualisieren der IDs

Zum Beispiel:

Nehmen wir an, Sie haben die folgenden 2 Tabellenschemata:

CREATE TABLE Parent
(
    ParentId INT UNSIGNED AUTO INCREMENT,
    Value INT UNSIGNED,
    PRIMARY KEY (ParentId)
)

CREATE TABLE Child
(
    ChildId INT UNSIGNED AUTO INCREMENT,
    ParentId INT UNSIGNED,
    PRIMARY KEY(ChildId),
    FOREIGN KEY(ParentId) REFERENCES Parent(ParentId)
)

Jetzt erscheinen die Lücken in Ihrer übergeordneten Tabelle.

Um Ihre Werte in Parent und Child zu aktualisieren, erstellen Sie zunächst eine temporäre Tabelle mit den Zuordnungen:

CREATE TEMPORARY TABLE NewIDs
(
    Id INT UNSIGNED AUTO INCREMENT,
    ParentID INT UNSIGNED
)

INSERT INTO NewIDs (ParentId)
SELECT
    ParentId
FROM
    Parent
ORDER BY
    ParentId ASC

Als Nächstes müssen wir MySQL anweisen, die Fremdschlüsselbeschränkung zu ignorieren, damit wir unsere Werte korrekt AKTUALISIEREN können. Wir werden diese Syntax verwenden:

SET foreign_key_checks = 0;

Dies führt dazu, dass MySQL beim Aktualisieren der Werte Fremdschlüsselprüfungen ignoriert, aber dennoch erzwingt, dass der richtige Werttyp verwendet wird (siehe MySQL-Referenz für Details).

Als nächstes müssen wir unsere Parent- und Child-Tabellen mit den neuen Werten aktualisieren. Dazu verwenden wir die folgende UPDATE-Anweisung:

UPDATE
    Parent,
    Child,
    NewIds
SET
    Parent.ParentId = NewIds.Id,
    Child.ParentId = NewIds.Id
WHERE
    Parent.ParentId = NewIds.ParentId AND
    Child.ParentId = NewIds.ParentId

Wir haben jetzt alle unsere ParentId-Werte korrekt auf die neuen, geordneten IDs aus unserer temporären Tabelle aktualisiert. Sobald dies abgeschlossen ist, können wir unsere Fremdschlüsselprüfungen erneut durchführen, um die referenzielle Integrität aufrechtzuerhalten:

SET foreign_key_checks = 1;

Schließlich löschen wir unsere temporäre Tabelle, um Ressourcen zu bereinigen:

DROP TABLE NewIds

Und das ist es.