Diseño de la base de datos: ¿Almacenar el estado o calcular el estado cada vez?

15

Digamos que tengo una aplicación de base de datos relacional y un objeto "usuario" y un objeto "mensaje". Ahora quiero mostrar el número de mensajes no leídos a este usuario.

¿Cuál es la mejor manera de archivar esto? ¿Introduzco un campo en el usuario y lo cuento si recibe un mensaje y lo reduzco si lo lee? ¿O ejecuto una consulta cada vez para calcular el número de mensajes para el usuario que están marcados como no leídos?

Creo que el primer enfoque es más complicado y propenso a errores, pero funcionará mejor que el segundo enfoque.

¿Cómo se hace esto normalmente o cuál es el mejor enfoque?

    
pregunta jan 24.06.2014 - 12:31

4 respuestas

14
  

¿Cómo se hace esto normalmente o cuál es el mejor enfoque?

El mejor enfoque es probarlo primero sin un campo adicional, medir el rendimiento y, si realmente resulta ser demasiado lento, intenta optimizar. Esto podría significar cambiar a su primer enfoque utilizando un campo adicional, pero también debería considerar probar otras opciones, por ejemplo, poniendo un índice adicional en los campos combinados ("no leído", "ID de usuario") en sus mensajes.

    
respondido por el Doc Brown 24.06.2014 - 12:48
9

La solución de libro de texto según teoría de la base de datos sería no tener valores en su base de datos que dependan de los valores de otros datos, porque estos son dependencias transitivas . Tener campos que son valores computados basados en otros campos es una violación de la normalización, porque conduce a información redundante.

Sin embargo, a veces lo que dice el libro de texto y cuál es el método más práctico en la práctica es diferente. Contar el número de mensajes no leídos en cada página vista puede ser una operación bastante costosa. Guardar el número en la tabla user sería mucho mejor para el rendimiento. El costo sería que es posible que existan inconsistencias en la base de datos: es posible que un mensaje se elimine, agregue o lea sin recordar actualizar también el contador no leído.

    
respondido por el Philipp 24.06.2014 - 13:03
4

El problema potencial es el rendimiento y todavía no tiene un problema de rendimiento. Hay muchas cosas que puede hacer dependiendo de la base de datos elegida para manejar esto en la solución # 1: indexación, hardware, almacenamiento en caché, etc. Todo esto depende de la frecuencia con la que el usuario necesita obtener un recuento actual de mensajes no leídos. Muchas de estas opciones no requieren codificación personalizada en el lado de la aplicación, por lo que puede implementarlas con un cambio de código o muy poco. Facilita el crecimiento con la aplicación.

Una vez que un usuario se conecta / inicia sesión, obtener el recuento de la base de datos una vez no es tan malo. ¿Su aplicación mantendrá una lista de mensajes en constante actualización como el correo electrónico? Obtener un recuento no leído desde aquí no requiere otro viaje a la base de datos y para recibir nuevos mensajes de todos modos se va a realizar un viaje de db.

¿Ir a la base de datos cada vez que se lee un mensaje para marcar el IsRead? campo es suficiente sin un nuevo cálculo de otro campo.

Con la solución # 2 (mantener un recuento en un campo / en el disco), ¿necesitará una rutina para reconstruir / recalcular periódicamente este campo cuando haya un problema? Y siempre hay problemas. ¿Vas a envolver todo esto en una transacción? ¿Cada vez que alguien le envía a alguien más un mensaje, puede fallar porque no puede actualizar el UnreadCount del usuario receptor debido a un bloqueo de la tabla de usuarios? ¿O va a crear una tabla separada para este campo?

    
respondido por el JeffO 24.06.2014 - 13:55
0

La forma en que lo haría es mediante la ejecución de una consulta cada vez, es decir, su segundo enfoque. Solo asegúrese de agregar un índice en su tabla de mensajes en la columna que actúa como una clave externa a la tabla de usuarios para mejorar el rendimiento de su consulta.

Luego, como dice el Doc, mida el rendimiento de este enfoque y luego podrá saber si necesita tomar un camino diferente.

    
respondido por el Jose B 24.06.2014 - 12:54

Lea otras preguntas en las etiquetas