it-swarm-pt.tech

Qual é a melhor maneira de implementar a exclusão suave?

No momento, estamos trabalhando em um projeto e precisamos implementar a exclusão suave para a maioria dos usuários (funções de usuário). Decidimos adicionar um campo "is_deleted = '0'" em cada tabela do banco de dados e defini-lo como '1' se determinadas funções de usuário pressionarem um botão de exclusão em um registro específico.

Para manutenção futura agora, cada consulta SELECT precisará garantir que eles não incluam registros em que is_deleted = '1'.

Existe uma solução melhor para implementar a exclusão suave?

Atualização: devo observar também que temos um banco de dados de auditoria que rastreia alterações (campo, valor antigo, novo valor, hora, usuário, ip) em todas as tabelas/campos no banco de dados de aplicativos.

43
Josh Smeaton

Você pode realizar todas as suas consultas em uma exibição que contém os WHERE IS_DELETED='0' cláusula.

46
David J. Sokol

Eu me inclinaria para um deleted_at coluna que contém o data e hora de quando a exclusão ocorre. Então você recebe um pouco de metadados gratuitos sobre a exclusão. Para o seu SELECT basta obter linhas WHERE deleted_at IS NULL

84
ctcherry

Tendo is_deleted coluna é uma abordagem razoavelmente boa. Se estiver no Oracle, para aumentar ainda mais o desempenho, recomendo particionar a tabela criando uma partição de lista em is_deleted coluna. As linhas excluídas e não excluídas estarão fisicamente em diferentes partições, embora, para você, seja transparente.

Como resultado, se você digitar uma consulta como

SELECT * FROM table_name WHERE is_deleted = 1

o Oracle executará a 'remoção da partição' e analisará apenas a partição apropriada. Internamente, uma partição é uma tabela diferente, mas é transparente para você como usuário: você poderá selecionar toda a tabela, independentemente de ser particionada ou não. Mas o Oracle poderá consultar SOMENTE a partição necessária. Por exemplo, suponha que você tenha 1000 linhas com is_deleted = 0 e 100000 linhas com is_deleted = 1 e você particiona a tabela em is_deleted. Agora, se você incluir a condição

WHERE ... AND IS_DELETED=0

o Oracle verificará SOMENTE a partição com 1000 linhas. Se a tabela não fosse particionada, seria necessário varrer 101000 linhas (ambas as partições).

20
Sergey Stadnik

Infelizmente, a melhor resposta depende do que você está tentando realizar com suas exclusões suaves e do banco de dados no qual está implementando isso.

No SQL Server, a melhor solução seria usar uma coluna delete_on/delete_at com um tipo de SMALLDATETIME ou DATETIME (dependendo da granularidade necessária) e tornar essa coluna anulável. No SQL Server, os dados do cabeçalho da linha contêm uma máscara de bits NULL para cada uma das colunas da tabela, por isso é um pouco mais rápido executar uma IS NULL ou IS NOT NULL do que é para verificar o valor armazenado em uma coluna.

Se você possui um grande volume de dados, convém particionar seus dados, por meio do próprio banco de dados ou de duas tabelas separadas (por exemplo, Products e ProductHistory) ou por uma exibição indexada.

Normalmente, evito campos de sinalização como is_deleted, is_archive, etc. porque eles carregam apenas um pedaço de significado. Um campo nulo delete_at, archived_at fornece um nível adicional de significado para você e para quem herda seu aplicativo. E evito campos de máscaras de bits como a praga, pois exigem uma compreensão de como a máscara de bits foi construída para compreender qualquer significado.

14
Jeremiah Peschka

se a tabela for grande e o desempenho for um problema, você sempre poderá mover os registros 'excluídos' para outra tabela, que possui informações adicionais, como hora da exclusão, quem excluiu o registro etc.

dessa forma, você não precisa adicionar outra coluna à sua tabela principal

13
Jiaaro

Isso depende de quais informações você precisa e quais fluxos de trabalho você deseja oferecer suporte.

Deseja poder:

  • sabe quais informações havia (antes de serem excluídas)?
  • sabe quando foi excluído?
  • sabe quem o excluiu?
  • sabe em que capacidade eles estavam agindo quando o deletaram?
  • ser capaz de cancelar a exclusão do registro?
  • ser capaz de saber quando foi excluído?
  • etc.

Se o registro foi excluído e excluído quatro vezes, é suficiente que você saiba que está atualmente em um estado não excluído ou deseja poder contar o que aconteceu nesse ínterim (incluindo quaisquer edições entre sucessivas) exclusões!)?

10
Daniel Fortunov

Cuidado com registros excluídos por software que causam violações de restrição de exclusividade. Se o seu banco de dados tiver colunas com restrições exclusivas, tenha cuidado para que os registros excluídos anteriormente não o impeçam de recriar o registro.

Pense no ciclo:

  1. criar usuário (login = JOE)
  2. exclusão reversível (defina a coluna excluída como não nula).
  3. (re) crie usuário (login = JOE). ERRO. LOGIN = JOE já está em uso

Segundo, crie resultados em uma violação de restrição porque login = JOE já está na linha excluída por software.

Algumas técnicas: 1. Mova o registro excluído para uma nova tabela. 2. Faça sua restrição de exclusividade na coluna de logon e delete_at timestamp

Minha opinião é +1 para mudar para a nova tabela. É preciso muita disciplina para manter o * AND delete_at = NULL * em todas as suas consultas (para todos os seus desenvolvedores)

7
Andy Rappaport

Você definitivamente terá um melhor desempenho se mover os dados excluídos para outra tabela como Jim disse, além de registrar quando eles foram excluídos, por que e por quem.

Adicionando where deleted = 0</code> para todas as suas consultas, as desacelerará significativamente e dificultará o uso de qualquer índice que você possa ter na tabela. Evite ter "sinalizadores" em suas tabelas sempre que possível.

4
Brent

você não menciona qual produto, mas o SQL Server 2008 e o postgresql (e outros, tenho certeza) permitem criar índices filtrados, para que você possa criar um índice de cobertura em que is_deleted = 0, atenuando alguns dos aspectos negativos dessa abordagem específica .

2
Andy Irving

Algo que eu uso em projetos é uma coluna statusInd tinyint não nula padrão 0 usando statusInd como uma máscara de bits permite que eu execute o gerenciamento de dados (excluir, arquivar, replicar, restaurar, etc.). Usando isso nas visualizações, eu posso fazer a distribuição de dados, a publicação etc. para os aplicativos que estão consumindo. Se o desempenho for uma preocupação em relação às visualizações, use pequenas tabelas de fatos para dar suporte a essas informações, eliminando o fato, eliminando a relação e permitindo exclusões escassas.

Escala bem e é centralizado em dados, mantendo a área de cobertura de dados bem pequena - chave para 350GB + dbs com preocupações em tempo real. O uso de alternativas, tabelas e gatilhos possui alguma sobrecarga que, dependendo da necessidade, pode ou não funcionar para você.

As auditorias relacionadas ao SOX podem exigir mais de um campo para ajudar no seu caso, mas isso pode ajudar. Aproveitar

1
Raymond Porrata

use uma visualização, função ou procedimento que verifique is_deleted = 0, ou seja, não selecione diretamente na tabela caso a tabela precise ser alterada posteriormente por outros motivos

e indexe a coluna is_deleted para tabelas maiores

como você já possui uma trilha de auditoria, o rastreamento da data de exclusão é redundante

0
Steven A. Lowe

Prefiro manter uma coluna de status, para usá-la em várias configurações diferentes, ou seja, publicada, privada, excluída, needsAproval ...

0
UnkwnTech

Crie um outro esquema e conceda tudo ao seu esquema de dados. Implemente o VPD em seu novo esquema para que todas as consultas tenham o predicado, permitindo a seleção da linha não excluída apenas anexada a ela. http://download.Oracle.com/docs/cd/E11882_01/server.112/e16508/cmntopc.htm#CNCPT62345

0
adsm

@AdditionalCriteria ("this.status <> 'excluído'")

coloque isso em cima da sua @entity

http://wiki.Eclipse.org/EclipseLink/Examples/JPA/SoftDelete

0
Kalpesh Soni