Eliminação física versus lógica / soft do registro do database?

Qual é a vantagem de fazer uma exclusão lógica / soft de um registro (ou seja, definir um sinalizador informando que o registro foi excluído) em oposição a deletar de fato ou fisicamente o registro?

Isso é prática comum?

Isso é seguro?

As vantagens são que você mantém o histórico (bom para auditoria) e não precisa se preocupar em fazer cascata de uma exclusão através de várias outras tabelas no database que fazem referência à linha que você está excluindo. A desvantagem é que você tem que codificar qualquer método de relatório / exibição para levar a bandeira em consideração.

Tanto quanto se é uma prática comum – eu diria que sim, mas como com qualquer coisa se você usá-lo depende de suas necessidades de negócios.

EDIT: pensamento de outra desvantagem – se você tiver índices exclusivos na tabela, registros excluídos ainda ocuparão o registro “um”, então você tem que codificar em torno dessa possibilidade também (por exemplo, uma tabela de usuário que tem um índice exclusivo em nome de usuário; Um registro excluído ainda bloquearia o nome de usuário dos usuários excluídos para novos registros. Trabalhando em torno disso, você poderia adicionar um GUID à coluna de nome de usuário excluído, mas é uma solução muito hacky que eu não recomendaria. É melhor ter apenas uma regra que, quando um nome de usuário for usado, nunca poderá ser substituído.

As lógicas excluem a prática comum? Sim, eu vi isso em muitos lugares. Eles estão seguros? Isso realmente depende de que eles sejam menos seguros do que os dados antes de serem excluídos?

Quando eu era líder em tecnologia, exigi que nossa equipe mantivesse todos os dados, eu sabia na época que estaríamos usando todos esses dados para criar vários aplicativos de BI, embora na época não soubéssemos quais seriam os requisitos. estar. Isso era bom do ponto de vista de auditoria, solução de problemas e geração de relatórios (esse era um site de comércio eletrônico / ferramentas para transactions B2B e, se alguém usasse uma ferramenta, queríamos registrá-la mesmo depois que a conta fosse desativada) teve várias desvantagens.

As desvantagens incluem (não incluindo outras já mencionadas):

  1. Implicações de desempenho de manter todos esses dados, Nós desenvolvemos várias estratégias de arquivamento. Por exemplo, uma área do aplicativo estava chegando perto de gerar cerca de 1 Gb de dados por semana.
  2. O custo de manter os dados aumenta com o tempo, enquanto o espaço em disco é barato, a quantidade de infraestrutura para manter e gerenciar terrabytes de dados on-line e off-line é muito grande. É preciso muito disco para redundância e o tempo das pessoas para garantir que os backups estejam se movendo rapidamente, etc.

Ao decidir usar exclusões lógicas, físicas ou arquivadas, eu me faria essas perguntas:

  1. Esses dados podem precisar ser reinseridos na tabela. Por exemplo, as Contas de Usuário se encheckboxm nessa categoria, pois você pode ativar ou desativar uma conta de usuário. Se este for o caso, uma exclusão lógica faz mais sentido.
  2. Existe algum valor intrínseco no armazenamento dos dados? Em caso afirmativo, quantos dados serão gerados. Dependendo disso, eu iria com uma exclusão lógica ou implementaria uma estratégia de arquivamento. Lembre-se de que você sempre pode arquivar registros excluídos logicamente.

Eu sou um desenvolvedor NoSQL, e no meu último trabalho, trabalhei com dados que sempre foram críticos para alguém, e se ele foi excluído por acidente no mesmo dia em que foi criado, não consegui encontrá-lo no último backup de ontem! Nessa situação, a exclusão suave sempre salvava o dia.

Fiz o apagamento usando timestamps, registrando a data em que o documento foi excluído:

 IsDeleted = 20150310 //yyyyMMdd 

Todos os domingos, um processo percorria o database e conferia o campo IsDeleted . Se a diferença entre a data atual e o registro de data e hora fosse maior que N dias, o documento foi excluído com dificuldade. Considerando que o documento ainda está disponível em algum backup, era seguro fazê-lo.

EDIT: Este caso de uso NoSQL é sobre grandes documentos criados no database, dezenas ou centenas deles todos os dias, mas não milhares ou milhões. Em geral, eles eram documentos com status, dados e anexos de processos de stream de trabalho. Essa foi a razão pela qual havia a possibilidade de um usuário excluir um documento importante. Esse usuário pode ser alguém com privilégios de administrador ou talvez o proprietário do documento, apenas para citar alguns.

TL; DR Meu caso de uso não era Big Data. Nesse caso, você precisará de uma abordagem diferente.

Pode ser um pouco tarde, mas sugiro a todos que verifiquem o post do blog de Pinal Dave sobre exclusão lógica / soft:

Eu simplesmente não gosto desse tipo de design [soft delete]. Acredito firmemente na arquitetura em que apenas os dados necessários devem estar em uma única tabela e os dados inúteis devem ser movidos para uma tabela arquivada. Em vez de seguir a coluna isDeleted, sugiro o uso de duas tabelas diferentes: uma com pedidos e outra com pedidos excluídos. Nesse caso, você terá que manter a tabela, mas, na realidade, é muito fácil de manter. Quando você escrever a instrução UPDATE na coluna isDeleted, escreva INSERT INTO em outra tabela e DELETE-a da tabela original. Se a situação for de reversão, escreva outro INSERT INTO e DELETE na ordem inversa. Se você está preocupado com uma transação com falha, envolva esse código em TRANSACTION.

Quais são as vantagens da mesa menor versus tabela maior nas situações descritas acima?

  • Uma mesa menor é fácil de manter
  • As operações de Reconstrução de Índice são muito mais rápidas
  • Mover os dados de arquivamento para outro grupo de arquivos reduzirá a carga do grupo de arquivos primário (considerando que todos os grupos de arquivos estão em sistemas diferentes) – isso também acelerará o backup.
  • As statistics serão atualizadas com frequência devido ao tamanho menor e isso demandará menos resources.
  • O tamanho do índice será menor
  • O desempenho da tabela irá melhorar com um tamanho de tabela menor.

Um padrão que usei é criar uma tabela de espelhamento e append um acionador na tabela principal, de modo que todas as exclusões (e atualizações, se desejado) sejam registradas na tabela de espelhamento.

Isso permite que você “reconstrua” registros excluídos / alterados, e você ainda pode apagar com dificuldade na tabela principal e mantê-la “limpa” – ela também permite a criação de uma function “desfazer” e você também pode gravar a data, hora , e usuário que fez a ação na mesa de espelho (inestimável em situações de caça às bruxas).

A outra vantagem é que não há nenhuma chance de include acidentalmente registros excluídos ao consultar o primário, a menos que você deliberadamente se dê ao trabalho de include registros da tabela de espelhamento (você pode querer mostrar registros ao vivo e excluídos).

Outra vantagem é que a tabela de espelhamento pode ser eliminada independentemente, já que não deve ter nenhuma referência de chave estrangeira, tornando essa operação relativamente simples em comparação com a limpeza de uma tabela primária que usa exclusões suaves, mas ainda possui conexões referenciais com outras tabelas .

Quais outras vantagens? – ótimo, se você tem um monte de codificadores trabalhando no projeto, fazendo leituras no database com habilidade mista e atenção aos níveis de detalhes, você não precisa ficar acordado à noite esperando que um deles não tenha esquecido de não include registros (lol, Não Incluir Registros Excluídos = Verdadeiro), o que resulta em coisas como exagerar dizer a posição de checkbox disponível do cliente que eles compram algumas ações com (ou seja, como em um sistema de negociação), quando você trabalha com sistemas de negociação, Descobrirá muito rapidamente o valor de soluções robustas, mesmo que elas tenham um pouco mais de “sobrecarga” inicial.

Exceções: – como um guia, use exclusões suaves para dados de “referência”, como usuário, categoria, etc, e exclusões difíceis para uma tabela de espelhamento para dados do tipo “fato”, ou seja, histórico de transactions.

Re: “Isso é seguro?” – isso depende do que você quer dizer.

Se você quer dizer que ao fazer a exclusão física, você impedirá que alguém encontre os dados excluídos , e sim, isso é mais ou menos verdadeiro; você está mais seguro ao excluir fisicamente os dados confidenciais que precisam ser apagados, porque isso significa que ele desapareceu do database permanentemente. (No entanto, perceba que pode haver outras cópias dos dados em questão, como em um backup, ou o log de transactions, ou uma versão gravada em trânsito, por exemplo, um sniffer de pacote – só porque você exclui do database não garantir que não foi salvo em outro lugar.)

Se você quer dizer que, ao fazer a exclusão lógica, seus dados são mais seguros, porque você nunca perderá nenhum dado , isso também é verdade. Isso é bom para cenários de auditoria; Eu costumo projetar dessa forma porque ele admite o fato básico de que uma vez que os dados são gerados, ele nunca irá realmente embora (especialmente se ele já teve a capacidade de ser, digamos, armazenado em cache por um mecanismo de busca da internet). Obviamente, um cenário de auditoria real exige que não apenas as exclusões sejam lógicas, mas que as atualizações também sejam registradas, juntamente com a hora da alteração e o agente que fez a alteração.

Se você quer dizer que os dados não cairão nas mãos de quem não deveria vê-los, então isso depende totalmente de sua aplicação e de sua estrutura de segurança. A esse respeito, a exclusão lógica não é mais ou menos segura do que qualquer outra coisa em seu database.

Eu geralmente uso exclusões lógicas – eu acho que elas funcionam bem quando você também arquiva os dados ‘apagados’ de forma intermitente em uma tabela arquivada (que pode ser pesquisada se necessário), portanto, sem chance de afetar o desempenho do aplicativo.

Funciona bem porque você ainda tem os dados se você já foi auditado. Se você deletar fisicamente, vai embora !

Sou um grande fã da exclusão lógica, especialmente para um aplicativo de linha de negócios ou no contexto de contas de usuário. Minhas razões são simples: muitas vezes eu não quero mais que um usuário possa usar o sistema (então a conta é marcada como deletada), mas se nós deletamos o usuário, perderíamos todo o trabalho deles e tal.

Outro cenário comum é que os usuários podem ser recriados um pouco depois de terem sido excluídos. É uma experiência muito melhor para o usuário ter todos os dados presentes como estavam antes de serem excluídos, em vez de precisar recriá-los.

Eu costumo pensar em excluir mais usuários como “suspendendo-os” indefinidamente. Você nunca sabe quando eles legitimamente precisam estar de volta.

Exclusões lógicas se forem difíceis na integridade referencial.

É o correto pensar em fazer quando há um aspecto temporal dos dados da tabela (são válidos FROM_DATE – TO_DATE).

Caso contrário, mova os dados para uma tabela de auditoria e exclua o registro.

Do lado positivo:

É a maneira mais fácil de reverter (se possível).

É fácil ver qual era o estado em um ponto específico no tempo.

É bastante normal nos casos em que você gostaria de manter um histórico de algo (por exemplo, contas de usuários como @Jon Dewees menciona). E certamente é uma ótima ideia se houver uma grande chance de os usuários solicitarem exclusões.

Se você está preocupado com a lógica de filtrar os registros excluídos de suas consultas ficando confusas e apenas complicando suas consultas, você pode simplesmente criar visualizações que fazem a filtragem para você e usar consultas contra isso. Isso impedirá o vazamento desses registros nas soluções de relatórios e tal.

Eu discordo totalmente da exclusão lógica porque você está exposto a muitos erros.

Primeiro de todas as consultas, cada consulta deve cuidar do campo IsDeleted e a possibilidade de erro se torna maior com consultas complexas.

Segundo o desempenho: imagine uma tabela com 100.000 recs com apenas 3 ativos, agora multiplique este número para as tabelas de seu database; Outro problema de desempenho é um possível conflito com novos registros com antigo (registros excluídos).

A única vantagem que vejo é o histórico de registros, mas existem outros methods para alcançar este resultado, por exemplo você pode criar uma tabela de log onde você pode salvar informações: TableName,OldValues,NewValues,Date,User,[..] onde *Values podem ser varchar e escrever os detalhes neste formulário fieldname : value ; [..] ou armazene a informação como xml .

Tudo isso pode ser conseguido via código ou Triggers, mas você é apenas uma tabela com todo o seu histórico. Outra opção é verificar se o mecanismo de database especificado é nativo para acompanhar a alteração, por exemplo, no database do SQL Server, há a Alteração de dados de rastreamento do SQL.

Existem requisitos além do design do sistema que precisam ser respondidos. Qual é o requisito legal ou estatutário na retenção de registros? Dependendo do que as linhas estão relacionadas, pode haver uma exigência legal de que os dados sejam mantidos por um determinado período de tempo após serem ‘suspensos’.

Por outro lado, o requisito pode ser que, uma vez que o registro seja ‘apagado’, ele seja real e irrevogavelmente excluído. Antes de tomar uma decisão, fale com seus stakeholders.

Eles não permitem que o database funcione como deve renderizar coisas como a funcionalidade de cascata inútil.

Para coisas simples, como inserções, no caso de reinserção, o código por trás dele duplica.

Você não pode simplesmente inserir, em vez disso, você precisa verificar se existe e inserir se ele não existir antes ou atualizar o sinalizador de exclusão, se isso acontecer, além de atualizar todas as outras colunas para os novos valores. Isso é visto como uma atualização para o log de transactions do database e não para uma nova inserção que causa logs de auditoria imprecisos.

Eles causam problemas de desempenho porque as tabelas estão ficando sobrecarregadas com dados redundantes. Ele joga com indexação especialmente com exclusividade.

Eu não sou um grande fã de exclusões lógicas.

Aplicativos móveis que dependem de synchronization podem impor o uso de exclusão lógica em vez de física: um servidor deve ser capaz de indicar ao cliente que um registro foi (marcado como) excluído e isso pode não ser possível se os registros forem fisicamente excluídos.

Eu costumava fazer soft-delete, apenas para manter registros antigos. Percebi que os usuários não se incomodam em ver registros antigos com a mesma frequência que eu pensava. Se os usuários quiserem visualizar registros antigos, eles podem apenas visualizar a partir do arquivo ou da tabela de auditoria, certo? Então, qual é a vantagem do soft-delete? Isso só leva a uma declaração de consulta mais complexa, etc.

A seguir estão as coisas que eu implementei antes que eu decidisse não deletar mais:

  1. implementar auditoria, para registrar todas as atividades (adicionar, editar, excluir). Certifique-se de que não haja nenhuma chave estrangeira vinculada à auditoria e garanta que essa tabela esteja protegida e que ninguém possa excluir, exceto os administradores.

  2. identificar quais tabelas são consideradas “tabela transacional”, o que muito provavelmente será mantido por muito tempo, e muito provavelmente o usuário pode querer visualizar os registros ou relatórios anteriores. Por exemplo; transação de compra. Esta tabela não deve apenas manter o id da tabela principal (como dept-id), mas também manter as informações adicionais, como o nome como referência (como nome-dept), ou quaisquer outros campos necessários para o relatório.

  3. Implemente o registro “ativo / inativo” ou “ativar / desativar” ou “ocultar / mostrar” da tabela mestre. Assim, em vez de excluir o registro, o usuário pode desativar / inativar o registro mestre. É muito mais seguro assim.

Apenas minha opinião de dois centavos.

Eu quase sempre apago soft e aqui meus 2 centavos:

  • Você pode restaurar os dados excluídos se um cliente solicitar que você faça isso. Mais clientes satisfeitos com exclusões suaves. Restaurar dados específicos de backups é complexo
  • verificar se isdeleted todos os lugares não é um problema, você deve verificar se há um userid de userid qualquer maneira (se o database contiver dados de vários usuários). Você pode impor a verificação por código, colocando essas duas verificações em uma function separada (ou usar exibições)
  • Deleção graciosa. Usuários ou processos que lidam com conteúdo excluído continuarão a “ver” até atingirem a próxima atualização. Este é um recurso muito desejável quando um processo está processando alguns dados que são subitamente excluídos
  • synchronization: se você precisar projetar um mecanismo de synchronization entre um database e aplicativos móveis, encontrará exclusões suaves tão menos dolorosas. Basicamente, você evita os paradoxos de synchronization, movendo o problema de um louco ADD / UPDATE / DELETE para um mais simples ADD / UPDATE

O Soft Delete é uma prática de programação que está sendo seguida na maioria dos aplicativos quando os dados são mais relevantes. Considere um caso de aplicação financeira em que uma exclusão pelo erro do usuário final pode ser fatal. Esse é o caso quando a exclusão flexível se torna relevante. Em soft delete, o usuário não está realmente excluindo os dados do registro, em vez disso, está sendo sinalizado como IsDeleted como true (por convenção normal).

No IE 6.x ou EF 7, o Softdelete é adicionado como um atributo, mas temos que criar um atributo personalizado para o momento.

Eu recomendo fortemente SoftDelete Em um projeto de database e é uma boa convenção para a prática de programação.

Bem! Como todos disseram, depende da situação.

Se você tiver um índice em uma coluna como UserName ou EmailID – e nunca espere que o mesmo UserName ou EmailID seja usado novamente; você pode ir com uma exclusão suave.

Dito isso, sempre verifique se sua operação SELECT usa a chave primária. Se sua instrução SELECT usar uma chave primária, adicionar um sinalizador com a cláusula WHERE não faria muita diferença. Vamos dar um exemplo (Pseudo):

Usuários da tabela (UserID [chave primária], EmailID, IsDeleted)

SELECT * FROM Usuários em que UserID = 123456 e IsDeleted = 0

Essa consulta não fará diferença em termos de desempenho, pois a coluna UserID tem uma chave primária. Inicialmente, ele examinará a tabela com base em PK e executará a próxima condição.

Casos em que as exclusões não podem funcionar:

Inscrever-se principalmente em todos os sites leva o EmailID como sua identificação exclusiva. Sabemos muito bem, uma vez que um EmailID é usado em um site como o facebook, G +, ele não pode ser usado por mais ninguém.

Chega um dia, quando o usuário deseja excluir seu perfil do site. Agora, se você fizer uma exclusão lógica, esse usuário não poderá se registrar nunca mais. Além disso, registrar-se novamente usando o mesmo EmailID não significaria restaurar o histórico inteiro. Todo mundo sabe, exclusão significa exclusão. Em tais cenários, temos que fazer uma exclusão física. Mas, para manter todo o histórico da conta, devemos sempre arquivar esses registros em tabelas de arquivo ou em tabelas excluídas.

Sim, em situações em que temos muitas tabelas estrangeiras, o manuseio é bastante complicado.

Lembre-se também de que as exclusões soft / lógicas aumentam o tamanho da tabela, portanto, o tamanho do índice.

Para responder ao comentário de Tohid, enfrentamos o mesmo problema em que queríamos persistir no histórico de registros e também não is_deleted se queríamos is_deleted coluna is_deleted ou não.

Estou falando sobre nossa implementação em Python e um caso de uso semelhante que atingimos.

Encontramos https://github.com/kvesteri/sqlalchemy-continuum, que é uma maneira fácil de obter a tabela de versões para a tabela correspondente. Linhas mínimas de código e captura histórico para adicionar, excluir e atualizar.

Isso serve mais do que apenas a coluna is_deleted . Você pode sempre reverter a tabela de versões para verificar o que aconteceu com esta input. Se a input foi excluída, atualizada ou adicionada.

Dessa forma, não precisávamos de is_deleted coluna is_deleted e nossa function delete era bem trivial. Dessa forma, também não precisamos nos lembrar de marcar is_deleted=False em qualquer uma das nossas APIs.

Na maioria das vezes, a exclusão de software é usada porque você não deseja expor alguns dados, mas precisa mantê-los por motivos históricos (um produto pode ser descontinuado, portanto, você não deseja novas transactions com ele, mas ainda precisa trabalhar com ele). a história da transação de venda). By the way, alguns estão copiando o valor da informação do produto nos dados da transação de venda em vez de fazer uma referência ao produto para lidar com isso.

Na verdade, parece mais uma reformulação de um recurso visível / oculto ou ativo / inativo. Porque esse é o significado de “excluir” no mundo dos negócios. Eu gostaria de dizer que os Exterminadores podem excluir pessoas, mas o chefe apenas os demite.

Esta prática é um padrão bastante comum e usada por muitos aplicativos por vários motivos. Como não é a única maneira de conseguir isso, você terá milhares de pessoas dizendo que isso é ótimo ou besteira e que ambos têm bons argumentos.

Do ponto de vista da segurança, o SoftDelete não replaceá o trabalho de Auditoria e também não replaceá o trabalho de backup. Se você tem medo de “inserir / excluir entre dois casos de backup”, leia sobre os modelos de recuperação total ou em massa. Admito que o SoftDelete poderia tornar o processo de recuperação mais trivial.

Até você para conhecer sua exigência.

Para dar uma alternativa, temos usuários usando dispositivos remotos atualizando via MobiLink. Se excluirmos registros no database do servidor, esses registros nunca serão marcados como excluídos nos bancos de dados do cliente.

Então nós fazemos os dois. Trabalhamos com nossos clientes para determinar por quanto tempo eles desejam recuperar dados. Por exemplo, geralmente os clientes e os produtos ficam ativos até que nosso cliente diga que eles devem ser excluídos, mas o histórico de vendas é mantido apenas por 13 meses e, em seguida, excluído automaticamente. O cliente pode querer manter os clientes e produtos excluídos por dois meses, mas manter o histórico por seis meses.

Então, executamos um script durante a noite que marca as coisas logicamente excluídas de acordo com esses parâmetros e, em seguida, dois / seis meses depois, qualquer coisa marcada como logicamente excluída hoje será excluída com dificuldade.

Somos menos sobre segurança de dados do que sobre ter bancos de dados enormes em um dispositivo cliente com memory limitada, como um smartphone. Um cliente que pede 200 produtos duas vezes por semana durante quatro anos terá mais de 81.000 linhas de história, das quais 75% o cliente não se importa se vê.

Tudo depende do caso de uso do sistema e de seus dados.

Por exemplo, se você está falando de um sistema regulado pelo governo (por exemplo, um sistema em uma empresa farmacêutica que é considerado parte do sistema de qualidade e deve seguir as diretrizes do FDA para registros eletrônicos), então é melhor não fazer exclusões difíceis! Um auditor da FDA pode entrar e pedir todos os registros no sistema relacionados ao número de produto ABC-123, e todos os dados devem estar disponíveis. Se o proprietário do processo de negócios informar que o sistema não deve permitir que ninguém use o número de produto ABC-123 em novos registros, use o método de exclusão flexível para torná-lo “inativo” no sistema, preservando os dados históricos.

No entanto, talvez seu sistema e seus dados tenham um caso de uso como “rastrear o clima no Pólo Norte”. Talvez você faça leituras de temperatura uma vez a cada hora e, no final do dia, agregue uma média diária. Talvez os dados por hora não sejam mais usados ​​após a agregação, e você excluirá as leituras por hora depois de criar o agregado. (Este é um exemplo inventado e trivial.)

A questão é que tudo depende do caso de uso do sistema e de seus dados, e não de uma decisão a ser tomada puramente do ponto de vista tecnológico.

É 2018, e uma grande desvantagem do soft delete é:

Conformidade com o GDPR

Seu aplicativo provavelmente não é compatível com GDPR se você excluir soft em qualquer coisa que seja considerada dados pessoais . [ 1 ] [ 2 ]

Também tenha em mente que, mesmo que sua empresa não esteja localizada na UE, contanto que você esteja lidando com dados de empresas, moradores ou cidadãos da UE, você terá que cumprir o GDPR. [ 3 ]