sql >> Base de Datos >  >> RDS >> Mysql

¿Cómo llenar los agujeros en los campos de incremento automático?

Estoy de acuerdo con @Aaron Digulla y @Shane N. Las lagunas no tienen sentido. Si SI significa algo, eso es un diseño de base de datos defectuoso. Punto.

Dicho esto, si absolutamente NECESITAS llenar estos agujeros, Y está ejecutando al menos MySQL 3.23, puede utilizar una TABLA TEMPORAL para crear un nuevo conjunto de ID. La idea aquí es que va a seleccionar todas sus ID actuales, en orden, en una tabla temporal como tal:

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

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

Esto le dará una tabla que asigna su ID anterior a una ID nueva que será de naturaleza secuencial, debido a la propiedad INCREMENTO AUTOMÁTICO de la columna NewId.

Una vez hecho esto, debe actualizar cualquier otra referencia al Id en "OldTable" y cualquier clave externa que utilice. Para hacer esto, probablemente necesitará DROP cualquier restricción de clave externa que tenga, actualice cualquier referencia en las tablas de OldId a NewId y luego reinstituya sus restricciones de clave externa.

Sin embargo, diría que no deberías hacer NINGUNA de esto, y solo comprenda que su campo Id existe con el único propósito de hacer referencia a un registro, y debe NO tienen alguna relevancia específica.

ACTUALIZAR:Agregar un ejemplo de actualización de los Id.

Por ejemplo:

Supongamos que tiene los siguientes 2 esquemas de tabla:

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

Ahora, las brechas están apareciendo en su tabla principal.

Para actualizar sus valores en Padre e Hijo, primero crea una tabla temporal con las asignaciones:

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

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

A continuación, debemos decirle a MySQL que ignore la restricción de clave externa para que podamos ACTUALIZAR correctamente nuestros valores. Usaremos esta sintaxis:

SET foreign_key_checks = 0;

Esto hace que MySQL ignore las comprobaciones de claves externas al actualizar los valores, pero seguirá imponiendo que se utilice el tipo de valor correcto (consulte Referencia de MySQL para detalles).

A continuación, debemos actualizar nuestras tablas principal y secundaria con los nuevos valores. Usaremos la siguiente instrucción UPDATE para esto:

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

Ahora hemos actualizado correctamente todos nuestros valores de ParentId a los nuevos ID ordenados de nuestra tabla temporal. Una vez que esto esté completo, podemos restablecer nuestras verificaciones de clave externa para mantener la integridad referencial:

SET foreign_key_checks = 1;

Finalmente, eliminaremos nuestra tabla temporal para limpiar los recursos:

DROP TABLE NewIds

Y eso es todo.