FolioPierEstudos de TI

Exclusão lógica

Nota 15 de 41 · 6 min de leitura
Nesta página
  1. Marcar em vez de remover
  2. Por que os sistemas marcam em vez de apagar
  3. A condição que esconde as linhas marcadas
  4. A linha marcada continua ocupando os valores
  5. A remoção definitiva

Um cliente excluído pelo sistema pode continuar aparecendo em uma consulta feita direto no banco, e um código de produto que o sistema diz não existir pode ser recusado como repetido em um cadastro novo. Os dois casos costumam ter a mesma origem. Muitos sistemas não removem a linha ao excluir um registro, apenas marcam a linha como excluída e deixam de mostrá-la. Esse modelo se chama exclusão lógica.

Marcar em vez de remover

Na exclusão física, o comando DELETE remove a linha da tabela. Na exclusão lógica, a aplicação grava uma marca na própria linha, com um UPDATE, e deixa de mostrar as linhas marcadas nas telas e nos relatórios. A linha continua na tabela, com todos os dados.

A marca pode ter formas diferentes:

  • uma coluna de indicação, como excluido, com a letra S nas linhas excluídas;
  • uma coluna de data, como excluido_em, que fica em NULL enquanto o registro está ativo e recebe o momento da exclusão;
  • a própria situação do registro, quando o sistema trata a exclusão como uma inativação.

No cenário, as tabelas de cadastro, como clientes e produtos, têm a coluna excluido, do tipo CHAR(1). A aplicação grava a letra N nos cadastros novos e a letra S quando um cadastro é excluído. Na tabela produtos, essa marca não se confunde com a coluna ativo. Um produto inativo continua no cadastro e apenas deixa de ser vendido, enquanto um produto excluído deixa de aparecer nas telas.

Por que os sistemas marcam em vez de apagar

  • Histórico: as vendas antigas continuam apontando para o cliente e para os produtos, e os relatórios do passado continuam completos.
  • Reversão: um cadastro excluído por engano volta às telas com a retirada da marca. Essa reversão deve passar pela aplicação, quando ela oferece esse recurso, porque a exclusão pode ter sido acompanhada de outras alterações feitas pelo sistema.
  • Sincronização: a marca é uma alteração da linha e pode ser enviada à matriz como qualquer outra alteração. Uma linha removida deixa de existir na loja, e em muitos mecanismos de sincronização não sobra nenhum vestígio da exclusão para ser enviado.
  • Origem do sistema: nos antigos bancos de dados em arquivos, a exclusão marcava o registro, e uma rotina de manutenção removia depois os registros marcados. Os sistemas que nasceram nesses bancos costumam conservar esse comportamento.

A condição que esconde as linhas marcadas

Uma consulta feita direto no banco não conhece a regra da aplicação e mostra também as linhas marcadas. Para contar o mesmo conjunto que o sistema mostra, a consulta precisa repetir a condição da aplicação.

Quando a coluna da marca é criada em uma tabela que já tem dados, as linhas antigas podem ficar com a coluna em NULL. Como uma comparação com NULL nunca resulta em verdadeiro, as condições excluido = 'N' e excluido <> 'S' deixam essas linhas de fora. A condição (excluido IS NULL OR excluido <> 'S') considera os dois casos. Duas contagens ajudam na comparação com a tela:

  • SELECT COUNT(*) FROM clientes WHERE (excluido IS NULL OR excluido <> 'S');: conta os clientes não marcados como excluídos;
  • SELECT COUNT(*) FROM clientes WHERE excluido = 'S';: conta os clientes marcados como excluídos.

Os parênteses mantêm as duas partes juntas quando a consulta tem outras condições, como um período ou uma situação. Mesmo com a marca considerada, a tela pode aplicar outros filtros, e a comparação entre uma contagem e a tela só vale quando os filtros são os mesmos.

A linha marcada continua ocupando os valores

A linha excluída logicamente conserva todos os valores, inclusive os que precisam ser únicos. Se a coluna codigo da tabela produtos tiver uma regra de valor único no banco, o cadastro de um produto novo com o código de um produto excluído é recusado com o erro 1062, de entrada duplicada, embora a busca do sistema não mostre nenhum produto com esse código. A consulta pelo código, sem a condição da marca, mostra a linha que ocupa o valor:

  • SELECT id, codigo, descricao, excluido FROM produtos WHERE codigo = '7891234567890';

A recusa também pode vir da própria aplicação. Se a rotina de cadastro procura o código em todas as linhas, inclusive nas marcadas, o sistema recusa o código repetido com uma mensagem própria.

A remoção definitiva

Três operações diferentes podem atingir um registro:

  • Exclusão pelo sistema: grava a marca, e a linha continua na tabela.
  • Limpeza pelo sistema: uma rotina de manutenção, quando existe, remove de vez as linhas marcadas.
  • DELETE direto no banco: remove a linha sem passar pela marca nem pelas outras ações da aplicação. A exclusão não fica registrada pelo sistema e pode não chegar à matriz.

Depois da remoção, a recuperação de um registro depende de uma cópia de segurança. A remoção das linhas também não reduz de imediato o tamanho dos arquivos da tabela no disco, porque o espaço liberado continua reservado para novas linhas.

No suporte

Antes de concluir que um registro sumiu ou que uma busca perdeu dados, convém consultar a linha direto no banco, sem nenhum filtro, e conferir a marca de exclusão. Uma contagem feita no banco só pode ser comparada com a tela quando repete a condição da marca e os demais filtros da tela.

Para guardar

  • Na exclusão lógica, a linha continua na tabela com uma marca, e a aplicação deixa de mostrá-la.
  • Uma consulta feita direto no banco mostra também as linhas marcadas.
  • A condição que esconde as linhas marcadas precisa considerar as linhas com a marca em NULL.
  • A linha marcada continua ocupando os valores únicos.
  • O DELETE direto remove a linha sem a marca e sem as demais ações da aplicação.
Uma contagem feita no banco mostra 1.000 clientes, e a tela do sistema mostra 980. O que verificar?

Se a consulta incluiu os clientes marcados como excluídos e se os demais filtros são iguais aos da tela. A consulta SELECT COUNT(*) FROM clientes WHERE excluido = 'S'; conta os marcados. A diferença de 20, sozinha, não prova que existem exatamente 20 clientes excluídos.

O cadastro de um produto novo foi recusado com o erro 1062, de entrada duplicada, mas a busca do sistema não encontra nenhum produto com esse código. Qual é a explicação provável?

Um produto excluído logicamente com o mesmo código. A linha continua na tabela, e a regra de valor único da coluna também vale para ela. A consulta pelo código, sem a condição da marca, mostra essa linha. A solução passa pela aplicação, como a reativação do produto antigo, e não pela remoção da linha, que pode estar ligada ao histórico de vendas.

Publicado a partir do Obsidian · FolioPier