Mysql
 sql >> Base de données >  >> RDS >> Mysql

Comment combler les trous dans les champs auto-incrémentés ?

Je suis d'accord avec @Aaron Digulla et @Shane N. Les lacunes n'ont pas de sens. S'ils FONT signifie quelque chose, c'est une conception de base de données défectueuse. Période.

Cela étant dit, si vous avez absolument BESOIN de combler ces trous, ET vous utilisez au moins MySQL 3.23, vous pouvez utiliser une TABLE TEMPORAIRE pour créer un nouvel ensemble d'ID. L'idée ici étant que vous allez sélectionner tous vos identifiants actuels, dans l'ordre, dans une table temporaire en tant que telle :

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

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

Cela vous donnera une table mappant votre ancien identifiant à un tout nouvel identifiant qui sera de nature séquentielle, en raison de la propriété AUTO INCREMENT de la colonne NewId.

Une fois cela fait, vous devez mettre à jour toute autre référence à l'ID dans "OldTable" et toute clé étrangère qu'il utilise. Pour ce faire, vous devrez probablement SUPPRIMER toutes les contraintes de clé étrangère que vous avez, mettre à jour toute référence dans les tables de l'OldId au NewId, puis rétablir vos contraintes de clé étrangère.

Cependant, je dirais que vous ne devriez pas faire AUCUN de cela, et comprenez simplement que votre champ Id existe dans le seul but de référencer un enregistrement, et ne devrait PAS avoir une pertinence spécifique.

MISE À JOUR :Ajout d'un exemple de mise à jour des identifiants

Par exemple :

Supposons que vous ayez les 2 schémas de table suivants :

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

Maintenant, les écarts apparaissent dans votre table Parent.

Afin de mettre à jour vos valeurs dans Parent et Enfant, vous créez d'abord une table temporaire avec les mappages :

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

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

Ensuite, nous devons dire à MySQL d'ignorer la contrainte de clé étrangère afin que nous puissions correctement mettre à jour nos valeurs. Nous utiliserons cette syntaxe :

SET foreign_key_checks = 0;

Cela amène MySQL à ignorer les vérifications de clé étrangère lors de la mise à jour des valeurs, mais il appliquera toujours le type de valeur correct est utilisé (voir Référence MySQL pour plus de détails).

Ensuite, nous devons mettre à jour nos tables Parent et Child avec les nouvelles valeurs. Nous utiliserons pour cela l'instruction UPDATE suivante :

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

Nous avons maintenant correctement mis à jour toutes nos valeurs ParentId avec les nouveaux identifiants ordonnés de notre table temporaire. Une fois cette opération terminée, nous pouvons réinstituer nos vérifications de clé étrangère pour maintenir l'intégrité référentielle :

SET foreign_key_checks = 1;

Enfin, nous allons supprimer notre table temporaire pour nettoyer les ressources :

DROP TABLE NewIds

Et c'est tout.