2008-09-19 7 views
18

OK, así que prácticamente cada aplicación basada en una base de datos tiene que lidiar con registros "no activos". O bien, eliminaciones suaves o marcando algo como "ignorado". Tengo curiosidad sobre si hay pensamientos de alternativas radicales en una columna 'activa' (o una columna de estado).bandera 'activa' o no?

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 las personas activas, es necesario utilizar

SELECT * FROM people WHERE active=True; 

¿Alguien sugiere que los registros no activos haría ser trasladado a una mesa separada y donde sea apropiado se hace una UNIÓN para unir los dos?

curiosidad sorprendente ...

EDIT: Quiero dejar en claro, ya voy en este desde una perspectiva purista. Puedo ver cómo el archivo de datos puede ser necesario para grandes cantidades de datos, pero no es de donde vengo. Si lo hace un SELECT * de la gente tendría sentido para mí que esas entradas son en cierto modo "activo"

Gracias

Respuesta

18

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

Aquí hay un ejemplo de cómo crear una tabla con particiones en Oracle. Oracle no tiene tipos de columnas booleanas, por lo que he modificado la estructura de su tabla para 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 quisiera, podría poner cada partición en diferentes espacios de tablas. También puede dividir sus índices también.

Por cierto, esto parece una repetición de la pregunta this, como novato debo preguntar, ¿cuál es el procedimiento para tratar con duplicados involuntarios?

Editar: a lo solicitado en los comentarios, siempre un ejemplo para la creación de una tabla con particiones en Oracle

+0

Podría ser más específico sobre cómo "particionar" la tabla. Me refiero a dar el código para cualquier RDBM que desee. –

+2

Según lo solicitado, agregó un ejemplo de una tabla particionada. Eche un vistazo al manual de conceptos de Oracle para obtener información detallada sobre la partición de tablas y índices. Uso Oracle 10.2 y hago referencia a toda la documentación desde aquí -> http://www.oracle.com/pls/db102/homepage –

+0

En lugar de una marca "activa", recomendaría utilizar un nombre de campo diferente, como "eliminado" . La razón es que cuando la siguiente persona trabaja en ella, puede confundirse con lo que significa "activo". Aparte de eso, +1 gran publicación. – NotMe

0

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

Solo necesita una unión de las tablas cuando alguien quiere ver todos los registros, activos o inactivos.

8

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

1

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

Podría moverlos a otra mesa como sugirió. Sugeriría mirar el porcentaje de registros activos/inactivos. Si tiene más de 20 o 30% de registros inactivos, entonces podría considerar moverlos a otro lugar. De lo contrario, no es un gran problema.

0

En la mayoría de los casos, un campo binario que indique la eliminación es suficiente. A menudo hay 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.

0

Pasar a una tabla separada y llevarlas de nuevo lleva tiempo. Dependiendo de la cantidad de registros que se desconectan y la frecuencia con la que deben devolvérselos, podría ser una buena idea o no.

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

1

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 F para mantenerla para fines de auditoría.

Ahora, nos movemos a un enfoque de dos tablas, cuando se inserta una nueva fila, la fila anterior se mueve a una tabla de historial. Esto nos da un mejor rendimiento para la mayoría de los casos, mirando los datos actuales.

El costo es un poco más que el método anterior, previamente tenía que actualizar e insertar, ahora tiene que insertar y actualizar (es decir, en lugar de insertar una nueva fila T, modifica la fila existente con todos los datos nuevos) , por lo tanto, el costo es solo el de pasar toda una fila de datos en lugar de pasar solo los cambios. Eso no va a tener ningún efecto.

La ventaja de rendimiento es que el índice de la tabla principal es significativamente más pequeño, y se puede optimizar sus espacios de tabla mejor (no crecerán bastante tanto!)

+0

También quiero pasar a un enfoque de dos tablas ya que trabajo en una base de datos antigua, mal diseñada, en la que algunas tablas tienen una columna "active = 'T/F'" para fines de auditoría y no tienen llaves principales. ¿Cómo manejaron los registros eliminados? ¿Usan un marcador para marcar una fila como activa/eliminada o también mueven el registro eliminado a la tabla de historial? Además, ¿mueve en cascada todos los datos relacionados a las tablas de historial también? ¡Gracias! –

+0

no se borra nada, mueve todos los registros a la tabla de historial y coloca una bandera sobre ellos.Si necesita registrar la eliminación (en lugar de modificarla posteriormente), solo necesita una nueva columna para marcarla como eliminada. Algún día alguien le preguntará acerca de los datos muertos y podrá responderlos correctamente. No incluimos registros relacionados en cascada; si cambian, sus datos deben actualizarse, pero a menos que la relación cambie, no es necesario que lo haga; sin embargo, nuestro esquema de datos fue lo suficientemente simple como para permitir esto, YMMV. – gbjbaanb

+0

Dicho todo esto, el nuevo sistema con el que trabajo escribe una tabla de auditoría completamente separada que simplemente registra todos los cambios, escribiendo "automáticamente" la columna X cambiada de Y a Z "para todos los cambios de datos importantes (no todo). – gbjbaanb

0

Utilizamos dos métodos para hacer frente a los registros inactivos. El método que usamos depende de la situación. Para registros que son esencialmente valores de búsqueda, utilizamos el campo de bit Activo. Esto nos permite desactivar entradas para que no se usen, pero también nos permite mantener la integridad de los datos con las relaciones.

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

0

La situación realmente dicta la solución, me parece:

Si la tabla contiene los usuarios, a continuación, varios campos de "bandera" se podrían utilizar. Uno para Suprimido, Deshabilitado, etc. O si el espacio es un problema, entonces bastaría con un indicador de deshabilitado y, en realidad, eliminar la fila si se han eliminado.

También depende de las políticas para almacenar datos. Si hay políticas para mantener los datos archivados, entonces probablemente sea necesaria una tabla separada después de un gran período de tiempo.

0

No - esto es una cosa bastante común - par de variaciones en función de las necesidades específicas (pero que ya les cubierta):

1) Si usted espera tener un montón de datos - como múltiples terabytes o más - no es una mala idea archivar los registros eliminados inmediatamente - aunque puede utilizar un enfoque combinado de marcado como eliminado y luego copiarlo en tablas de archivo.

2) Por supuesto, la opción de borrar un disco aún existe, aunque los desarrolladores usamos como ratas de paquete de datos. Sugiero que mire el proceso de negocio y decida si ahora hay alguna necesidad de mantener los datos, si los hay, hazlos ... si no los hay, probablemente deberías sentirte libre solo para tirar las cosas ...de nuevo, según el escenario empresarial específico.

3

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

2

Mover cosas inactivas suele ser una idea estúpida. Es un montón de sobrecarga con mucho potencial para los errores, todo se vuelve más complicado, como desarchivar el material, etc. ¿Qué haces con los datos relacionados? Si mueve todo eso, también, debe modificar cada consulta. Si no lo mueve, ¿qué ventaja esperaba obtener?

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

2

Creo que mirándolo estrictamente como un dato, entonces la forma en que se muestra en la publicación original es correcta. La información de la bandera activa depende directamente de la clave primaria y debe estar en la tabla.

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

0

Desde una "perspectiva purista", el modelo real no diferencia entre una vista y una mesa: ambas son relaciones. De modo que el uso de una vista que usa el discriminador es perfectamente significativo y válido siempre que las entidades sean nombradas correctamente, p. Person/ActivePerson.

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

+0

esquemas de nombres son una preferencia. Creo que solo se recomienda seguir con la forma de decidir para todas las tablas. A muchos les gusta considerar que una relación contiene muchos de los artículos. –

1

Los 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 lo que sucede cuando tienes 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)

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

Antes de completar su esquema con indicadores útiles, tenga en cuenta cómo va a acceder a esos datos.

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

+3

La cardinalidad no debe afectar el uso de un índice. La selectividad lo hace. –

0

En cuanto a la indexación del booleano, por qué no:

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

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

Cuestiones relacionadas