2011-03-17 20 views
7

Dado un sitio como StackOverflow, ¿sería mejor crear la columna num_comments para almacenar cuántos comentarios tiene un envío y luego actualizarlo cuando se realiza un comentario o simplemente consultar el número de filas con la función COUNT? Parece que este último sería más legible y elegante, pero el primero sería más eficiente. ¿Qué piensa SO?¿Cuál es mejor diseño de base de datos?

+1

Si SO necesitara unir tablas para mostrar conteos de comentarios, no existiría. Pero preocupándose por lo que sucederá cuando su sitio reciba millones de visitas de páginas por día es, digamos, prematuro, por lo que en sus propios proyectos, vaya con el 'COUNT'. – Jon

+5

No optimice prematuramente. Mantenga las bases de datos normalizadas hasta que necesite desnormalizarlas. – Quentin

+1

@Jon: interesante ... ¿podría elaborar o proporcionar un enlace? Estoy loco fuera del modelo relacional, pero siempre listo para aprender ... –

Respuesta

7

Definitivamente utilizar COUNT. Almacenar la cantidad de comentarios es una des-normalización clásica que produce dolores de cabeza. Es ligeramente más eficiente para la recuperación, pero hace que las inserciones sean mucho más caras: cada nuevo comentario requiere no solo una inserción en la tabla de comentarios, sino también un bloqueo de escritura en la fila que contiene el recuento de comentarios.

+1

no es una desnormalización más una optimización y requiere algunos factores desencadenantes, ¡apenas un dolor de cabeza! –

+0

@JonBlack - Sí, es una optimización (aunque, como dije en mi respuesta, no está tan claro si la "optimización" vale la pena). Al mismo tiempo, definitivamente es una desnormalización. Específicamente, una columna 'num_comments' viola la tercera forma normal porque introduce una dependencia no clave, un valor que no depende de la clave pero, en este caso, de los valores que muy probablemente provienen de una tabla completamente diferente. En cuanto a los dolores de cabeza, el problema no es solo escribir "algunos desencadenantes", sino también tener que mantener los desencadenantes junto con todo lo demás a medida que evoluciona el DB. –

3

El primero no está normalizado, pero producirá un mejor rendimiento (asumiendo muchas más lecturas que escrituras).

Este último es más normalizado, pero requerirá más recursos y, por lo tanto, será menos eficiente.

Que es mejor se reduce a los requisitos de la aplicación.

2

Sugeriría contar registros de comentarios. Aunque el otro método sería más rápido, se presta a una base de datos más limpia. Agregar una columna de conteo sería un tipo de duplicación de datos, por no mencionar requerir pasos e insertar códigos adicionales.

Si esperaba millones de comentarios, entonces puede elegir el enfoque de columna de recuento.

2

Estoy de acuerdo con @Oded. Depende de los requisitos de la aplicación y también la forma activa es el sitio, sin embargo aquí es también mi granito de arena

  • me gustaría tratar de evitar las escrituras que tendrán que ser hecho por factores desencadenantes, las actualizaciones para enviar mesa cuando nuevos comentarios se agregan
  • Si le preocupa informar los datos, no lo haga en un sistema transaccional. Cree una base de datos de informes y actualícela periódicamente.
2

La forma "correcta" de diseñar es utilizar otra tabla, únala y COUNT. Esto es consistente con lo que database normalization enseña.

El problema con la normalización es que no se puede escalar. Solo hay tantas maneras de despellejar a un gato, por lo que si tiene millones de consultas por día y muchas de ellas involucran la tabla X, el rendimiento de la base de datos va por debajo del nivel dado que el servidor también tiene que lidiar con escrituras simultáneas, transacciones, etc.

Para tratar este problema, una práctica común es sharding. El sharding tiene el efecto secundario de que las filas de una tabla no están almacenadas en la misma ubicación física, y una consecuencia principal de esto es que ya no puede JOIN; ¿Cómo se puede JOIN contra media mesa y recibir resultados significativos? Y, obviamente, intentar JOIN contra todas las particiones de una tabla y fusionar los resultados va a ser peor que la enfermedad.

Así que verá que no solo la alternativa que examina se usa en la práctica para lograr un alto rendimiento, sino también que hay pasos aún más radicales que los ingenieros pueden y deben realizar.

Por supuesto, a menos que haga tenga problemas de rendimiento, fragmentación o incluso desnormalización es simplemente haciendo su vida más difícil sin ningún beneficio tangible.

+0

¿Cómo inclina la balanza hacia incluir la columna num_comments? –

Cuestiones relacionadas