mejor - postgresql vs sql server
indicador ''activo'' o no? (16)
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.
De acuerdo, prácticamente todas las aplicaciones basadas en bases de datos tienen 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).
Por ejemplo, si tuviera una lista de personas
CREATE TABLE people (
id INTEGER PRIMARY KEY,
name VARCHAR(100),
active BOOLEAN,
...
);
Eso significa obtener una lista de personas activas, debes usar
SELECT * FROM people WHERE active=True;
¿Alguien sugiere que los registros no activos se trasladarán a una tabla separada y, cuando corresponda, se realizará una UNIÓN para unir los dos?
Curiosidad impactante ...
EDITAR: Debería dejar en claro, me refiero a esto 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 haces un SELECT * FROM personas, tendría sentido para mí que esas entradas estén, en cierto sentido, "activas"
Gracias
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 sobre personas, independientemente del estado actual de sus datos.
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 utiliza el discriminador es perfectamente significativo y válido siempre que las entidades estén nombradas correctamente, por ejemplo, Person / ActivePerson.
Además, desde una "perspectiva purista", la tabla debería llamarse persona, no personas, ya que el nombre de la relación refleja una tupla, no el conjunto completo.
En cuanto a la indexación del 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.
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.
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.
La situación realmente dicta la solución, me parece:
Si la tabla contiene usuarios, se podrían usar varios campos de "marca". 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.
Las banderas binarias como esta en su esquema son una MALA idea. Considera la consulta
SELECT count(*) FROM users WHERE active=1
Parece lo suficientemente 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)
¡¡EXCEPTO!! ¡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, considere cómo va a acceder a esos datos.
https://.com/questions/108503/mysql-advisable-number-of-rows
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?
No, esto es algo bastante común: un par de variaciones según los requisitos específicos (pero ya las cubrió):
1) Si espera tener un conjunto completo de datos, como múltiples terabytes o más, no es una mala idea archivar los registros eliminados inmediatamente, aunque puede usar un enfoque combinado de marcado como eliminado y luego copiarlo en tablas de archivo.
2) Por supuesto, todavía existe la opción de eliminar un disco duro -aunque los desarrolladores usamos suelen ser ratas de paquete de datos-, sugiero que debe observar el proceso de negocio y decidir si ahora hay alguna necesidad de guardar los datos, si hay ... hazlo ... si no lo hay, probablemente deberías sentirte libre solo para tirar las cosas ... otra vez, de acuerdo con el escenario de negocios específico.
Particiona la tabla en el indicador activo, de modo 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 particionada en Oracle. Oracle no tiene tipos de columnas booleanas, por lo que he modificado 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 quisiera, podría poner cada partición en diferentes espacios de tabla. También puede dividir sus índices también.
Por cierto, esto parece una repetición de esta pregunta, como un novato que tengo que preguntar, ¿cuál es el procedimiento para tratar con duplicados involuntarios?
Editar: como se solicita en los comentarios, proporciona un ejemplo para crear una tabla con particiones en Oracle
Pasar a una mesa separada y volver a subirlos toma 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 utilizan 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.
Sí, lo haríamos. Actualmente tenemos la columna "active = ''T / F''" en muchas de nuestras tablas, principalmente para mostrar la última fila. 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, anteriormente 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 que el costo es solo eso de pasar toda una fila de datos en lugar de pasar solo los cambios. Eso no va a tener ningún efecto.
El beneficio de rendimiento es que el índice de su tabla principal es significativamente más pequeño, y puede optimizar sus espacios de tabla mejor (¡no crecerán tanto!)
Usamos ambos métodos para tratar con 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.
Usamos 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.
Usamos 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.
Entonces, solo se requiere una unión de las tablas cuando alguien quiere ver todos los registros, activos o inactivos.
Usamos una enumeración (''ACTIVE'', ''INACTIVE'', ''DELETED'') en la mayoría de las tablas, así que en realidad tenemos una bandera de 3 vías. Me parece que funciona bien para nosotros en diferentes situaciones. Su experiencia puede ser diferente.