Mysql
 sql >> Base de Dados >  >> RDS >> Mysql

Como preencher os buracos nos campos de incremento automático?


Eu concordo com @Aaron Digulla e @Shane N. As lacunas não têm sentido. Se eles FAZEM significa alguma coisa, que é um projeto de banco de dados falho. Período.

Dito isso, se você PRECISA preencher esses buracos, E você está executando pelo menos o MySQL 3.23, você pode utilizar uma TABELA TEMPORÁRIA para criar um novo conjunto de IDs. A ideia aqui é que você selecione todos os seus IDs atuais, em ordem, em uma tabela temporária 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

Isso fornecerá uma tabela mapeando seu ID antigo para um ID totalmente novo que será de natureza sequencial, devido à propriedade AUTO INCREMENT da coluna NewId.

Feito isso, você precisa atualizar qualquer outra referência ao Id em "OldTable" e qualquer chave estrangeira que ele utilize. Para fazer isso, você provavelmente precisará DROP quaisquer restrições de chave estrangeira que tiver, atualizar qualquer referência nas tabelas de OldId para NewId e, em seguida, reinstituir suas restrições de chave estrangeira.

No entanto, eu diria que você não deve fazer NENHUM disso, e apenas entenda que seu campo de ID existe com o único propósito de fazer referência a um registro e deve NÃO tem alguma relevância específica.

ATUALIZAÇÃO:Adicionando um exemplo de atualização dos IDs

Por exemplo:

Digamos que você tenha os 2 esquemas de tabela a seguir:
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)
)

Agora, as lacunas estão aparecendo na sua tabela Pai.

Para atualizar seus valores em Pai e Filho, primeiro crie uma tabela temporária com os mapeamentos:
CREATE TEMPORARY TABLE NewIDs
(
    Id INT UNSIGNED AUTO INCREMENT,
    ParentID INT UNSIGNED
)

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

Em seguida, precisamos dizer ao MySQL para ignorar a restrição de chave estrangeira para que possamos ATUALIZAR corretamente nossos valores. Usaremos esta sintaxe:
SET foreign_key_checks = 0;

Isso faz com que o MySQL ignore as verificações de chave estrangeira ao atualizar os valores, mas ainda forçará que o tipo de valor correto seja usado (consulte referência MySQL para detalhes).

Em seguida, precisamos atualizar nossas tabelas Pai e Filho com os novos valores. Usaremos a seguinte instrução UPDATE para isso:
UPDATE
    Parent,
    Child,
    NewIds
SET
    Parent.ParentId = NewIds.Id,
    Child.ParentId = NewIds.Id
WHERE
    Parent.ParentId = NewIds.ParentId AND
    Child.ParentId = NewIds.ParentId

Agora atualizamos todos os nossos valores de ParentId corretamente para os novos IDs ordenados de nossa tabela temporária. Quando isso estiver concluído, podemos reinstituir nossas verificações de chave estrangeira para manter a integridade referencial:
SET foreign_key_checks = 1;

Por fim, descartaremos nossa tabela temporária para limpar os recursos:
DROP TABLE NewIds

E é isso.