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

Hvordan udfylder man hullerne i auto-inkrementering felter?

Jeg er enig med @Aaron Digulla og @Shane N. Hullerne er meningsløse. Hvis de GØR betyder noget, det er et mangelfuldt databasedesign. Periode.

Når det er sagt, hvis du absolut SKAL udfylde disse huller, OG du kører mindst MySQL 3.23, kan du bruge en MIDLERTIDIG TABEL til at oprette et nyt sæt id'er. Ideen her er, at du vil vælge alle dine nuværende ID'er i rækkefølge i en midlertidig tabel som sådan:

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

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

Dette vil give dig en tabel, der kortlægger dit gamle id til et helt nyt id, der vil være sekventiel på grund af egenskaben AUTO INCREMENT i kolonnen NewId.

Når dette er gjort, skal du opdatere enhver anden reference til Id'et i "OldTable" og enhver fremmednøgle, den bruger. For at gøre dette skal du sandsynligvis FRA eventuelle fremmednøglebegrænsninger, du har, opdatere enhver reference i tabeller fra OldId til NewId og derefter genindføre dine fremmednøglebegrænsninger.

Jeg vil dog påstå, at du ikke bør gøre NOT af dette, og bare forstå, at dit id-felt udelukkende eksisterer med det formål at henvise til en post, og bør IKKE har nogen specifik relevans.

OPDATERING:Tilføjelse af et eksempel på opdatering af Id'erne

For eksempel:

Lad os sige, at du har følgende 2 tabelskemaer:

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

Nu dukker hullerne op i din overordnede tabel.

For at opdatere dine værdier i Forælder og barn skal du først oprette en midlertidig tabel med tilknytningerne:

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

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

Dernæst skal vi bede MySQL om at ignorere den fremmede nøgle-begrænsning, så vi korrekt kan OPDATERE vores værdier. Vi vil bruge denne syntaks:

SET foreign_key_checks = 0;

Dette får MySQL til at ignorere kontrol af fremmednøgle, når værdierne opdateres, men det vil stadig håndhæve den korrekte værditype, der bruges (se MySQL-reference for detaljer).

Dernæst skal vi opdatere vores forældre- og børnetabeller med de nye værdier. Vi vil bruge følgende UPDATE-erklæring til dette:

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

Vi har nu opdateret alle vores ParentId-værdier korrekt til de nye, bestilte Id'er fra vores midlertidige tabel. Når dette er fuldført, kan vi genindføre vores udenlandske nøglekontrol for at opretholde referenceintegritet:

SET foreign_key_checks = 1;

Til sidst vil vi droppe vores midlertidige tabel for at rydde op i ressourcer:

DROP TABLE NewIds

Og det er det.



  1. Android:Bulk Insert, når InsertHelper er forældet

  2. En fortælling om to klyngefaktorer

  3. 6 måder at vælge duplikerede rækker i SQLite

  4. DBCC_OBJECT_METADATA-låsen