Pregunta

Bien, prácticamente todas las aplicaciones basadas en bases de datos tienen que lidiar con registros "no activos".Ya sea, eliminaciones temporales o marcar algo como "para ser ignorado".Tengo curiosidad por saber si hay ideas alternativas radicales en una columna "activa" (o una columna de estado).

Por ejemplo, si tuviera una lista de personas

CREATE TABLE people (
  id       INTEGER PRIMARY KEY,
  name     VARCHAR(100),
  active   BOOLEAN,
  ...
);

Eso significa que para obtener una lista de personas activas, debes usar

SELECT * FROM people WHERE active=True;

¿Alguien sugiere que los registros no activos se muevan a una tabla separada y, cuando sea apropiado, se haga una UNIÓN para unir los dos?

Curiosidad sorprendente...

EDITAR: Debo dejar claro que lo hago desde una perspectiva purista.Puedo ver cómo el archivado de datos puede ser necesario para grandes cantidades de datos, pero no es de ahí de donde vengo.Si haces un SELECT * FROM personas tendría sentido para mí que esas entradas sean en cierto sentido "activas"

Gracias

¿Fue útil?

Solución

Se particiona la tabla en el indicador activo, de modo que los registros activos estén en una partición y los registros inactivos en la otra partición.Luego, crea una vista activa para cada tabla que automáticamente tiene el filtro activo.El motor de consulta de la base de datos restringe automáticamente la consulta a la partición que tiene los registros activos, lo cual es mucho más rápido que incluso usar un índice en ese indicador.

A continuación se muestra un ejemplo de cómo crear una tabla particionada en Oracle.Oracle no tiene tipos de columnas booleanas, por lo que modifiqué la estructura de su tabla para propósitos de Oracle.

CREATE TABLE people
(
   id       NUMBER(10),
   name     VARCHAR2(100),
   active   NUMBER(1)
)
PARTITION BY LIST(active)
(
   PARTITION active_records VALUES (0)
   PARTITION inactive_records VALUES (1)
);

Si quisieras, podrías poner cada partición en diferentes espacios de tabla.También puede particionar sus índices.

Por cierto, esto parece una repetición de este Pregunta, como novato debo preguntar: ¿cuál es el procedimiento para tratar con duplicados no deseados?

Editar: Según lo solicitado en los comentarios, proporcionó un ejemplo para crear una tabla particionada en Oracle

Otros consejos

Bueno, para asegurarse de dibujar solo registros activos en la mayoría de las situaciones, puede crear vistas que solo contengan los registros activos.De esa forma es mucho más fácil no dejar de lado la parte activa.

Usamos un enum('ACTIVE','INACTIVE','DELETED') en la mayoría de las tablas, por lo que en realidad tenemos un indicador de 3 vías.Creo que funciona bien para nosotros en diferentes situaciones.Su experiencia puede ser diferente.

Mover cosas inactivas suele ser una idea estúpida.Es una gran cantidad de gastos generales con muchas posibilidades de errores, todo se vuelve más complicado, como desarchivar el material, etc.¿Qué haces con los datos relacionados?Si mueve todo eso también, tendrá que modificar cada consulta.Si no lo mueves, ¿qué ventaja esperabas obtener?

Eso lleva al siguiente punto:¿POR QUÉ lo moverías?Una tabla correctamente indexada requiere una búsqueda adicional cuando el tamaño se duplica.Cualquier mejora en el rendimiento seguramente será insignificante.¿Y por qué pensarías en ello hasta un futuro lejano cuando realmente tengas problemas de rendimiento?

Creo que si lo miramos estrictamente como un dato, la forma en que se muestra en la publicación original es correcta.El dato del indicador activo depende directamente de la clave principal y debe estar en la tabla.

Esa tabla contiene datos sobre las personas, independientemente del estado actual de sus datos.

La bandera activa es un poco fea, pero es simple y funciona bien.

Podrías moverlos a otra mesa como sugeriste.Sugeriría mirar el porcentaje de registros activos/inactivos.Si tiene más del 20 o 30 % de registros inactivos, podría considerar moverlos a otra parte.De lo contrario, no es gran cosa.

Sí, lo haríamos.Actualmente tenemos la columna "active='T/F'" en muchas de nuestras tablas, principalmente para mostrar la fila "más reciente".Cuando se inserta una nueva fila, la fila T anterior se marca como F para conservarla a efectos de auditoría.

Ahora, pasamos a un enfoque de 2 tablas: cuando se inserta una nueva fila, la fila anterior se mueve a una tabla de historial.Esto nos brinda un mejor rendimiento en la mayoría de los casos, si observamos los datos actuales.

El costo es ligeramente mayor que el método anterior, antes tenías que actualizar e insertar, ahora tienes que insertar y actualizar (es decir, en lugar de insertar una nueva fila T, modificas la fila existente con todos los datos nuevos), por lo que el costo es simplemente pasar una fila completa de datos en lugar de pasar solo los cambios.Eso difícilmente tendrá algún efecto.

El beneficio de rendimiento es que el índice de su tabla principal es significativamente más pequeño y puede optimizar mejor sus espacios de tabla (¡no crecerán tanto!)

Indicadores binarios como este en su esquema son una MALA idea.Considere la consulta

SELECT count(*) FROM users WHERE active=1

Parece bastante simple.Pero, ¿qué sucede cuando tiene una gran cantidad de usuarios, tantos que sería necesario agregar un índice a esta tabla?De nuevo, parece sencillo

ALTER TABLE users ADD INDEX index_users_on_active (active)

¡¡EXCEPTO!!¡Este índice es inútil porque la cardinalidad de esta columna es exactamente dos!Cualquier optimizador de consultas de bases de datos ignorará este índice debido a su baja cardinalidad y realizará un escaneo de la tabla.

Antes de llenar su esquema con indicadores útiles, considere cómo va a acceder a esos datos.

https://stackoverflow.com/questions/108503/mysql-advisable-number-of-rows

Usamos banderas activas con bastante frecuencia.Sin embargo, si su base de datos va a ser muy grande, podría ver el valor de migrar valores inactivos a una tabla separada.

Entonces solo necesitaría una unión de las tablas cuando alguien quiera ver todos los registros, activos o inactivos.

En la mayoría de los casos, es suficiente un campo binario que indique la eliminación.A menudo existe un mecanismo de limpieza que eliminará esos registros eliminados después de un cierto período de tiempo, por lo que es posible que desee iniciar el esquema con una marca de tiempo eliminada.

Pasar a una mesa separada y volver a subirlos lleva tiempo.Dependiendo de cuántos registros se desconectan y con qué frecuencia necesita recuperarlos, puede que sea una buena idea o no.

Si la mayoría no regresa una vez que están enterrados y solo se usan para resúmenes/informes/lo que sea, entonces su tabla principal será más pequeña, las consultas más simples y probablemente más rápidas.

Utilizamos ambos métodos para tratar con registros inactivos.El método que utilizamos depende de la situación.Para registros que son esencialmente valores de búsqueda, utilizamos el campo Bit activo.Esto nos permite desactivar las entradas para que no se utilicen, pero también nos permite mantener la integridad de los datos con las relaciones.

Usamos el método "mover a la tabla de separación" donde los datos ya no son necesarios y los datos no son parte de una relación.

Creo que la situación realmente dicta la solución:

Si la tabla contiene usuarios, se podrían utilizar varios campos de "marca".Uno para eliminado, deshabilitado, etc.O si el espacio es un problema, entonces sería suficiente marcar deshabilitado y luego eliminar la fila si se ha eliminado.

También depende de las políticas de almacenamiento de datos.Si existen políticas para mantener los datos archivados, lo más probable es que después de un largo período de tiempo sea necesaria una tabla separada.

No, esto es algo bastante común, hay un par de variaciones según los requisitos específicos (pero ya las cubriste):

1) Si espera tener un MONTÓN completo de datos, como varios terabytes o más, no es una mala idea archivar los registros eliminados inmediatamente, aunque puede utilizar un enfoque combinado de marcar como eliminados y luego copiarlos en tablas de archivo.

2) Por supuesto, la opción de eliminar un registro todavía existe, aunque nosotros, los desarrolladores, tendemos a ser ratas de datos. Le sugiero que observe el proceso de negocio y decida si ahora es necesario conservar los datos, si hay - hazlo...si no es así, probablemente debería sentirse libre de tirar las cosas... nuevamente, de acuerdo con el escenario comercial específico.

Desde una "perspectiva purista", el modelo real no diferencia entre una vista y una tabla: ambas son relaciones.De modo que el uso de una vista que utiliza el discriminador es perfectamente significativo y válido siempre que las entidades tengan el nombre correcto, p.Persona/Persona Activa.

Además, desde una "perspectiva purista", la tabla debería denominarse persona, no personas, ya que el nombre de la relación refleja una tupla, no el conjunto completo.

En cuanto a indexar el booleano, ¿por qué no?

ALTER TABLE users ADD INDEX index_users_on_active (id, active) ;  

¿Eso no mejoraría la búsqueda?
Sin embargo, no sé cuánto de esa respuesta depende de la plataforma.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top