Pregunta

Estoy trabajando en un sitio web con una base de datos normalizada simple.

Hay una tabla llamada Páginas y una tabla llamada Vistas. Cada vez que se ve una página, se registra un registro único de esa vista en la tabla Vistas.

Cuando visualizo una página en el sitio, uso un simple MySQL COUNT () para totalizar el número de vistas para mostrar.

El diseño de la base de datos parece estar bien, excepto por este problema: no sé cómo recuperar las 10 páginas más vistas entre miles.

¿Debería desnormalizar la tabla de Páginas agregando una columna Pages.views para contener el número total de vistas para cada página? ¿O hay una manera eficiente de consultar las 10 páginas más vistas?

¿Fue útil?

Solución

   SELECT p.pageid, count(*) as viewcount FROM 
   pages p
   inner join views v on p.pageid = v.pageid
   group by p.pageid
   order by count(*) desc   
   LIMIT 10 OFFSET 0;

No puedo probar esto, pero algo en ese sentido. No almacenaría el valor a menos que sea necesario debido a restricciones de rendimiento (acabo de aprender el término "optimización prematura", y parece aplicarse si lo hace).

Otros consejos

Depende del nivel de información que intente mantener. Si desea registrar quién vio cuándo? Entonces la mesa separada está bien. De lo contrario, una columna para Vistas es el camino a seguir. Además, si mantiene una columna separada, encontrará que la tabla se bloqueará con más frecuencia ya que cada vista de página intentará actualizar la columna para su fila correspondiente.

Select pageid, Count(*) as countCol from Views
group by pageid order by countCol DESC
LIMIT 10 OFFSET 0;

Probablemente incluiría la columna de vistas en la tabla de páginas.

Me parece una ruptura de la normalización perfectamente razonable. Especialmente porque no puedo imaginar que elimines vistas para que no esperes que el conteo se salga de control. La integridad referencial no parece supercrítica en este caso.

La normalización de la base de datos se trata de la forma más eficiente / menos redundante de almacenar datos. Esto es bueno para el procesamiento de transacciones, pero a menudo entra directamente en conflicto con la necesidad de recuperar los datos de manera eficiente. El problema generalmente se resuelve con tablas derivadas (índices, vistas materializadas, tablas de resumen ...) con datos preprocesados ??más accesibles. La palabra de moda (ligeramente anticuada) aquí es Data Warehousing.

Creo que desea mantener su tabla de Páginas normalizada, pero tiene una tabla adicional con los totales. Dependiendo de cuán recientes deben ser esos recuentos, puede actualizar la tabla cuando actualice la tabla original, o puede tener un trabajo en segundo plano para recalcular periódicamente los totales.

También desea hacer esto solo si realmente se encuentra con un problema de rendimiento, lo cual no ocurrirá a menos que tenga una gran cantidad de registros o una gran cantidad de accesos concurrentes. Mantenga su código flexible para poder cambiar entre tener la tabla y no tenerla.

La desnormalización definitivamente funcionaría en este caso. Su pérdida es el espacio de almacenamiento adicional utilizado por la columna adicional.

Alternativamente, puede configurar un trabajo programado para completar esta información todas las noches, siempre que su tráfico sea bajo, x período de tiempo.

En este caso, estaría perdiendo la capacidad de saber instantáneamente los recuentos de su página a menos que ejecute esta consulta manualmente.

La desnormalización definitivamente puede emplearse para aumentar el rendimiento.

--Kris

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