Estou acostumado a ver linhas da tabela com colunas como 'DeletedDate' nelas e não gosto delas. A própria noção de 'excluído' é que a entrada não deveria ter sido feita em primeiro lugar. Praticamente, eles não podem ser removidos do banco de dados, mas eu não os quero com meus dados quentes. Linhas excluídas logicamente são, por definição, dados frios, a menos que alguém queira especificamente ver dados excluídos.
Além disso, toda consulta escrita deve excluí-los especificamente e os índices precisam considerá-los também.
O que eu gostaria de ver é uma alteração no nível da arquitetura do banco de dados e no nível do aplicativo: crie um esquema chamado 'excluído'. Cada tabela definida pelo usuário tem um equivalente idêntico no esquema 'excluído' com um campo extra contendo metadados - o usuário que a excluiu e quando. Chaves estrangeiras estão exigindo a criação.
Em seguida, exclusões tornam-se exclusões de inserção. Primeiro, a linha a ser excluída é inserida na sua contraparte de esquema 'excluída'. A linha em questão na tabela principal pode ser excluída. Lógica extra, no entanto, precisa ser adicionada em algum lugar ao longo da linha. Violações de chave estrangeira podem ser tratadas.
Chaves estrangeiras devem ser manuseadas adequadamente. É uma prática recomendada excluir uma linha logicamente, mas cujo principal / exclusivo tenha colunas em outras tabelas que se referem a ela. Isso não deveria acontecer de qualquer maneira. Um trabalho regular pode remover linhas de viúva (linhas cujas chaves primárias não têm referências em outras tabelas, apesar da presença de uma chave estrangeira. No entanto, essa é a lógica de negócios.
O benefício geral é a redução de metadados na tabela e a melhoria de desempenho que ela traz. A coluna 'deleteDate' diz que essa linha não deveria estar aqui, mas, por uma questão de conveniência, deixamos lá e deixamos a consulta SQL lidar com isso. Se uma cópia da linha excluída for mantida em um esquema 'excluído', a tabela principal com os dados ativos terá uma porcentagem maior de dados ativos (supondo que eles sejam arquivados em tempo hábil) e menos colunas de metadados desnecessárias. Os índices e as consultas não precisam mais considerar esse campo. Quanto menor o tamanho da linha, mais linhas podem ser ajustadas em uma página, mais rápido o SQL Server pode funcionar.
A principal desvantagem é o tamanho da operação. Agora existem duas operações em vez de uma, além da lógica extra e tratamento de erros. Isso pode levar a mais bloqueios do que a atualização de uma única coluna seria necessária. A transação mantém bloqueios na tabela por mais tempo e há duas tabelas envolvidas. Excluir dados de produção, pelo menos na minha experiência, é algo raramente feito. Mesmo assim, em uma das tabelas principais, 7,5% dos quase 100 milhões de entradas tem uma entrada na coluna 'Data excluída'.
Como resposta à pergunta, o aplicativo teria que estar ciente de 'cancelar a exclusão'. Basta fazer o mesmo na ordem inversa: insira a linha do esquema 'excluído' na tabela principal e, em seguida, exclua a linha do esquema 'excluído. Novamente, é necessária alguma lógica extra e manipulação de erros para garantir erros, problemas com chaves estrangeiras e similares.