Mysql
 sql >> Database >  >> RDS >> Mysql

Come riempire i buchi nei campi con incremento automatico?

Sono d'accordo con @Aaron Digulla e @Shane N. Le lacune sono prive di significato. Se Fanno significa qualcosa, questo è un design del database imperfetto. Punto.

Detto questo, se DEVI assolutamente riempire questi buchi, E stai eseguendo almeno MySQL 3.23, puoi utilizzare una TABELLA TEMPORANEA per creare un nuovo set di ID. L'idea qui è che selezionerai tutti i tuoi ID correnti, in ordine, in una tabella temporanea in quanto tale:

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

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

Questo ti darà una tabella che associa il tuo vecchio ID a un ID nuovo di zecca che sarà di natura sequenziale, a causa della proprietà AUTO INCREMENT della colonna NewId.

Fatto ciò, è necessario aggiornare qualsiasi altro riferimento all'ID in "OldTable" e qualsiasi chiave esterna utilizzata. Per fare ciò, probabilmente dovrai eliminare tutti i vincoli di chiave esterna che hai, aggiornare qualsiasi riferimento nelle tabelle da OldId a NewId e quindi reinserire i tuoi vincoli di chiave esterna.

Tuttavia, direi che non dovresti fare NESSUNO di questo, e capisci solo che il tuo campo ID esiste al solo scopo di fare riferimento a un record e che NON avere una rilevanza specifica.

AGGIORNAMENTO:aggiunta di un esempio di aggiornamento degli ID

Ad esempio:

Supponiamo che tu abbia i seguenti 2 schemi di tabelle:

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)
)

Ora, gli spazi vuoti vengono visualizzati nella tabella principale.

Per aggiornare i tuoi valori in Parent and Child, devi prima creare una tabella temporanea con le mappature:

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

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

Successivamente, dobbiamo dire a MySQL di ignorare il vincolo della chiave esterna in modo da poter AGGIORNARE correttamente i nostri valori. Useremo questa sintassi:

SET foreign_key_checks = 0;

Ciò fa sì che MySQL ignori i controlli della chiave esterna durante l'aggiornamento dei valori, ma imporrà comunque che venga utilizzato il tipo di valore corretto (vedi Riferimento MySQL per dettagli).

Successivamente, dobbiamo aggiornare le nostre tabelle padre e figlio con i nuovi valori. Useremo la seguente istruzione UPDATE per questo:

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

Ora abbiamo aggiornato correttamente tutti i nostri valori ParentId ai nuovi ID ordinati dalla nostra tabella temporanea. Una volta completato, possiamo ripristinare i nostri controlli di chiave esterna per mantenere l'integrità referenziale:

SET foreign_key_checks = 1;

Infine, elimineremo la nostra tabella temporanea per ripulire le risorse:

DROP TABLE NewIds

E questo è tutto.