Tabela de marca de exclusão vs sinalizador excluído em cenários de sincronização de banco de dados e exclusão suave

17

Preciso acompanhar os itens excluídos para as necessidades de sincronização do cliente.

Em geral, é melhor adicionar uma tabela de marca de exclusão e um gatilho que rastreie quando uma linha foi excluída do banco de dados do servidor - basicamente adicionando uma nova linha à tabela de marca de exclusão com os dados do item excluído - ou manter os itens no tabela original e sinalize -as como excluídas, geralmente com uma coluna do tipo bit, para indicar que uma linha foi excluída e outra coluna para rastrear quando a exclusão ocorreu?

Lorenzo Polidori
fonte

Respostas:

17

Em geral, é melhor conhecer os requisitos específicos e não tomar decisões de design com base no que funciona melhor na maioria das situações. Qualquer um poderia ser preferível. Aqui estão alguns detalhes a serem coletados:

  • Quão rápido as exclusões precisam ser?
  • Qual a velocidade da exclusão de exclusões?
  • Com que frequência os dados excluídos serão consultados e os dados que não foram excluídos?
  • Qual é a velocidade da consulta dos dados excluídos?
  • Você precisa preservar apenas itens ou alterações excluídos também?
  • Você precisa manter a tabela / índices na tabela principal pequena?
  • Quais tecnologias de particionamento e / ou rastreamento de alterações estão disponíveis na plataforma de banco de dados?
  • Quanto espaço em disco está disponível?
  • A exclusão ocorrerá em tempo real ou em operações em lote?
Leigh Riffel
fonte
Entendo, é uma questão de trocar entre diferentes requisitos de sistema. Se eu precisar de exclusões / exclusões rápidas, o sinalizador seria preferível, mas se eu precisar de consultas rápidas sobre itens excluídos e também na tabela principal e talvez eu precise acompanhar qualquer tipo de alteração, a abordagem de marca de exclusão pode ser Melhor.
Lorenzo Polidori
Você entendeu. Pode até haver casos em que outra opção seria preferível. Por exemplo, se você apenas precisou que as exclusões programáveis ​​estivessem disponíveis por 24 horas, no Oracle, você pode considerar a definição de um tempo garantido de retenção para desfazer e, em seguida, usar consultas de flashback para ver os dados excluídos.
Leigh Riffel
5

Talvez você deva combinar os dois métodos de propósito. Por quê ???

Vamos usar essa tabela (dialeto MySQL)

CREATE TABLE mydata
(
    id int not null auto_increment
    firstname varchar(16) not null,
    lastname varchar(16) not null,
    zipcode char(5) not null,
    ...
    deleted tinyint not null default 0
    KEY (deleted,id),
    KEY (deleted,lastname,firstname,id),
    KEY (deleted,zipcode,id),
    KEY (lastname,firstname),
    KEY (zipcode),
    PRIMARY KEY (id)
);

Observe que, com exceção da PRIMARY KEY, todos os índices que você cria devem ser precedidos pelo deletedsinalizador e terminar com o id.

Vamos criar a tabela de marca para exclusão

CREATE TABLE mytomb SELECT id FROM mydata WHERE 1=2;
ALTER TABLE mytomb ADD PRIMARY KEY (id);

Se sua tabela já tiver um deletedsinalizador, você poderá preencher a tabela tommstone

INSERT INTO mytomb SELECT id FROM mydata WHERE deleted = 1;

OK, agora os dados e a lápide estão preparados. Como você executa exclusões?

Digamos que você esteja excluindo todas as pessoas no CEP 07305. Você executaria o seguinte:

INSERT IGNORE INTO mytomb SELECT id FROM mydata WHERE deleted=0 AND zipcode='07305';
UPDATE mydata SET deleted=1 WHERE deleted=0 AND zipcode='07305';

OK, isso parece um monte de sobrecarga de qualquer maneira que você olha para ele.

Agora, você deseja ver todos os dados excluídos? Aqui estão duas maneiras diferentes:

  • SELECT * FROM mydata WHERE deleted=1;
  • SELECT B.* FROM mytomb A INNER JOIN mydata B USING (id);

Se o número de IDs no mytomb for maior que 5% da contagem de linhas de mydata, será uma verificação completa da tabela. Caso contrário, uma varredura de índice com uma pesquisa para cada linha. Observe quaisquer benchmarks nesses aspectos. Pesquise os planos de explicação.

Agora, você quer ver todas as pessoas no CEP 07304? Aqui estão duas maneiras diferentes:

  • SELECT * FROM mydata WHERE deleted=1 AND zipcode='07304';
  • SELECT A.* FROM mydata A LEFT JOIN mytomb B USING (id) WHERE B.id IS NULL AND A.zipcode='07304'

Que tal exclusões em massa? Aqui estão duas maneiras diferentes:

  • DELETE FROM mydata WHERE deleted=1;
  • DELETE B.* FROM mytomb A INNER JOIN mydata B USING (id); DELETE FROM mytomb;

CONCLUSÃO

Agora, não estou dizendo para manter os dois métodos. Fazer isso ao longo do tempo revela qual método é mais rápido em termos de operacionalidade geral. Você deve decidir quais parâmetros de referência para consultar dados ativos, consultar dados excluídos e exclusões em massa que funcionam melhor para você.

RolandoMySQLDBA
fonte
Existe uma vantagem em usar as duas técnicas continuamente? Ou você está sugerindo apenas usá-los em paralelo para avaliar o desempenho e depois se comprometer com um ou outro?
Jon of All Trades