Tombstone Table vs Deleted Flag en sincronización de bases de datos y escenarios de borrado suave


17

Necesito hacer un seguimiento de los elementos eliminados para las necesidades de sincronización del cliente.

En general, ¿es mejor agregar una tabla de lápidas y un disparador que rastrea cuando se eliminó una fila de la base de datos del servidor, básicamente agregando una nueva fila a la tabla de lápidas con los datos del elemento eliminado, o para mantener los elementos en el tabla original y marcarlos como eliminados, generalmente con una columna de tipo bit, para indicar que se elimina una fila y otra columna para rastrear cuando se produjo la eliminación.

Respuestas:


17

En general, es mejor conocer los requisitos específicos y no tomar decisiones de diseño basadas en lo que funciona mejor en la mayoría de las situaciones. Cualquiera de los dos podría ser preferible. Aquí hay algunos detalles para reunir:

  • ¿Qué tan rápido deben ser las eliminaciones?
  • ¿Qué tan rápido deben ser las eliminaciones?
  • ¿Con qué frecuencia se consultarán los datos eliminados y se consultarán los datos que no se hayan eliminado?
  • ¿Qué tan rápido deben ser las consultas de datos eliminados?
  • ¿Necesita conservar solo los elementos eliminados o los cambios también?
  • ¿Necesita mantener pequeñas las tablas / índices en la tabla primaria?
  • ¿Qué tecnologías de partición y / o seguimiento de cambios están disponibles en la plataforma de base de datos?
  • ¿Cuánto espacio en disco hay disponible?
  • ¿Se producirá la eliminación sobre la marcha o en operaciones por lotes?

Ya veo, es una cuestión de compensación entre los diferentes requisitos del sistema. Si necesito eliminaciones / eliminaciones rápidas, sería preferible la marca, pero si necesito consultas rápidas sobre elementos eliminados y también sobre la tabla primaria y tal vez necesito hacer un seguimiento de cualquier tipo de cambios, el enfoque de lápida podría ser mejor.
Lorenzo Polidori

Lo tienes. Incluso podría haber casos en los que sería preferible otra opción. Por ejemplo, si solo necesita que las eliminaciones por software estén disponibles durante 24 horas, en Oracle podría considerar establecer un tiempo de retención de deshacer garantizado y luego usar consultas flashback para ver los datos eliminados.
Leigh Riffel

5

Tal vez deberías combinar los dos métodos a propósito. Por qué ???

Usemos esa tabla (dialecto 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)
);

Tenga en cuenta que, con la excepción de la CLAVE PRIMARIA, cada índice que haga debe ir precedido por la deletedbandera y terminar con id.

Creemos la tabla de lápidas

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

Si su tabla ya tiene una deletedbandera, puede llenar la tabla tommstone

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

Bien, ahora los datos y la lápida están preparados. ¿Cómo se realizan las eliminaciones?

Supongamos que está eliminando a todas las personas en el código postal 07305. Ejecutarías lo siguiente:

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, esto parece un montón de gastos generales de cualquier manera que lo mires.

Ahora, ¿quieres ver todos los datos eliminados? Aquí hay dos formas diferentes:

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

Si el número de identificadores en mytomb es mayor al 5% del número de filas de mydata, es un escaneo completo de la tabla. De lo contrario, una exploración de índice con una búsqueda para cada fila. Tenga en cuenta los puntos de referencia a este respecto. Busque los planes de explicación.

Ahora, ¿quieres ver a todas las personas en el código postal 07304? Aquí hay dos formas 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'

¿Qué hay de las eliminaciones masivas? Aquí hay dos formas diferentes:

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

CONCLUSIÓN

Ahora, no estoy diciendo que conserve ambos métodos. Hacer esto con el tiempo revela qué método es más rápido en términos de operabilidad general. Debe decidir qué puntos de referencia para consultar datos en vivo, consultar datos eliminados y eliminaciones masivas funcionan mejor para usted.


¿Existe alguna ventaja de usar ambas técnicas de manera continua? ¿O sugiere simplemente usarlos en paralelo para evaluar el rendimiento y luego comprometerse con uno u otro?
Jon of All Trades
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.