Há formas eficientes de prevenir redundância de dados no MySQL. Caso você ainda não tenha adotado uma medida preventiva, vou abordar duas soluções que corrigem o problema e previnem sua ocorrência no futuro.
Crie um índice único com o modificador IGNORE
Vamos usar a seguinte tabela como cenário:
select * from contatos; +----------+------------------+------------------------------+ | nome | sobrenome | email | +----------+------------------+------------------------------+ | woody | woodpecker | woodywoodpecker@gmail.com | | woody | woodpecker | woodywoodpecker@hotmail.com | | winnie | woodpecker | winniewoodpecker@yahoo.com.br| +----------+------------------+------------------------------+ 3 rows in set (0.00 sec)
Note que o nome e o sobrenome do Picapau se repetem, embora cada registro tenha email diferente. Neste exemplo, vamos mostrar como eliminar um deles.
Se o problema ainda não existisse, poderíamos evitar toda esta história daqui pra frente, com o seguinte comando, que cria uma chave única para os campos nome, sobrenome
:
create unique index idx_contatos on contatos(nome,sobrenome);
Mas, se você tentar executá-lo em uma situação em que há registros redundantes, vai obter o erro:
ERROR 1062 (23000): Duplicate entry 'woody-woodpecker' for key 'idx_contatos'
Para contornar este erro, podemos usar o comando alter ignore table
. Veja como:
alter ignore table contatos add unique idx_contatos(nome,sobrenome);
O sistema deve retornar algo semelhante ao que se vê abaixo:
Query OK, 3 rows affected (0.00 sec)
Records: 3 Duplicates: 1 Warnings: 0
Agora, vamos executar um select
para ver como está a nossa tabela:
select * from contatos; +----------+------------------+------------------------------+ | nome | sobrenome | email | +----------+------------------+------------------------------+ | woody | woodpecker | woodywoodpecker@gmail.com | | winnie | woodpecker | winniewoodpecker@yahoo.com.br| +----------+------------------+------------------------------+ 2 rows in set (0.00 sec)
Não funcionou?
Este procedimento pode não ter efeito em algumas versões do MySQL, quando você não estiver usando tabelas MyISAM. Por esta razão, alguns administradores optam por converter as tabelas InnoDB para MyISAM antes de aplicar o procedimento. Depois convertem de volta. Veja como:
alter table contatos engine MyISAM; alter ignore table contatos add unique index idx_contatos(nome,sobrenome); alter table contatos engine InnoDB;
Criando uma tabela auxiliar
Na abordagem anterior, vimos como eliminar os registros duplicados na tabela MySQL, sem a possibilidade, contudo, de escolher qual deles seria descartado e qual permaneceria. Esta possibilidade de escolha faz sentido quando os registros não são exatamente iguais, como era o caso – possuíam endereços de email diferentes.
Vamos começar por criar uma nova tabela vazia, com a mesma estrutura da tabela original:
create table contatosnovo like contatos;
Em seguida, criamos o índice único na nova tabela:
alter table contatosnovo add unique index idx_contatos(nome,sobrenome);
Agora, carregamos a tabela, selecionando um registro de cada grupo de registros duplicados. Na sentença select
é possível selecionar o valor que nos interessa de cada um dos campos. No exemplo, que segue, vamos selecionar sempre o registro que contiver o endereço de correio eletrônico mais curto, nos casos de duplicidade:
insert into contatosnovo (nome,sobrenome,email) ( select nome, sobrenome, email from ( select nome,sobrenome,email from contatos order by length(email) asc ) table_tmp group by nome,sobrenome );
Agora, verifique o resultado:
select * from contatosnovo; +--------+------------+-------------------------------+ | nome | sobrenome | email | +--------+------------+-------------------------------+ | winnie | woodpecker | winniewoodpecker@yahoo.com.br | | woody | woodpecker | woodywoodpecker@gmail.com | +--------+------------+-------------------------------+ 2 rows in set (0.00 sec)
Findo este procedimento, vamos remover a tabela original e mudar o nome da tabela temporária:
drop table contatos; alter table contatosnovo rename to contatos;
Pronto! Problema resolvido.
Compartilhe! 😉
Posted from WordPress for Android
2 replies on “Como eliminar registros duplicados no MySQL.”
Boa sua explicação mas está retornando erro:
comando:
alter ignore table posts add unique index idx_posts(title)
erro:
Mensagens do MySQL : Documentação
#1170 – Coluna BLOB ‘title’ usada na especificação de chave sem o comprimento da chave
muito bom as explicações