sql >> Database >  >> RDS >> Mysql

Hoe de gaten in velden voor automatisch verhogen op te vullen?

Ik ben het eens met @Aaron Digulla en @Shane N. De hiaten zijn zinloos. Als ze DOEN iets betekenen, dat is een gebrekkig databaseontwerp. Periode.

Dat gezegd hebbende, als je deze gaten absoluut MOET opvullen, EN u minimaal MySQL 3.23 gebruikt, kunt u een TIJDELIJKE TABEL gebruiken om een ​​nieuwe set ID's te maken. Het idee hier is dat je al je huidige ID's in volgorde gaat selecteren in een tijdelijke tabel als zodanig:

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

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

Dit geeft je een tabel die je oude Id toewijst aan een geheel nieuwe Id die sequentieel van aard zal zijn, vanwege de AUTO INCREMENT-eigenschap van de NewId-kolom.

Zodra dit is gebeurd, moet u elke andere verwijzing naar de id in "OldTable" en elke gebruikte externe sleutel bijwerken. Om dit te doen, moet u waarschijnlijk alle beperkingen voor externe sleutels DROPPEN, alle verwijzingen in tabellen bijwerken van de OldId naar de NewId en vervolgens uw beperkingen voor externe sleutels opnieuw instellen.

Ik zou echter willen beweren dat u EEN . niet moet doen hiervan, en begrijp gewoon dat uw Id-veld uitsluitend bestaat om naar een record te verwijzen, en NIET enige specifieke relevantie hebben.

UPDATE:een voorbeeld toevoegen van het bijwerken van de ID's

Bijvoorbeeld:

Stel dat u de volgende 2 tabelschema's heeft:

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 verschijnen de hiaten in uw bovenliggende tabel.

Om uw waarden in Parent en Child bij te werken, maakt u eerst een tijdelijke tabel met de toewijzingen:

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

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

Vervolgens moeten we MySQL vertellen om de externe sleutelbeperking te negeren, zodat we onze waarden correct kunnen BIJWERKEN. We zullen deze syntaxis gebruiken:

SET foreign_key_checks = 0;

Dit zorgt ervoor dat MySQL controles van buitenlandse sleutels negeert bij het bijwerken van de waarden, maar het zal nog steeds afdwingen dat het juiste waardetype wordt gebruikt (zie MySQL-referentie voor details).

Vervolgens moeten we onze bovenliggende en onderliggende tabellen bijwerken met de nieuwe waarden. We zullen hiervoor het volgende UPDATE-statement gebruiken:

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

We hebben nu al onze ParentId-waarden correct bijgewerkt naar de nieuwe, bestelde Ids uit onze tijdelijke tabel. Zodra dit is voltooid, kunnen we onze externe sleutelcontroles opnieuw instellen om de referentiële integriteit te behouden:

SET foreign_key_checks = 1;

Ten slotte zullen we onze tijdelijke tabel laten vallen om bronnen op te ruimen:

DROP TABLE NewIds

En dat is dat.



  1. Hoe krijg ik de laatst ingevoerde ID van een MySQL-tabel in PHP?

  2. MariaDB CURRENT_USER() uitgelegd

  3. Sommige ELKE geaggregeerde transformaties zijn verbroken

  4. Resultaten van twee query's combineren in een enkele dataset