2009-03-04 17 views
10

Tengo que recopilar estadísticas por días, semanas, meses y años de actividad del usuario para un sitio. Soy la etapa de diseño de DB y quería hacer esta etapa correctamente, ya que facilitaría mi vida de codificación.Estructura de la base de datos para almacenar estadísticas por día, semana, mes, año

Lo que tengo que hacer es simplemente incrementar los valores en los campos en 1 en el DB cada vez que ocurre una actividad. Entonces puedo retirar la fecha todos los días, cada semana, cada mes y año. ¿Cómo debería estructurarse mi DB? Disculpas si esta es una pregunta simple para la mayoría. También sería genial si esta estructura pudiera extenderse para que pueda ser desglosada por otras categorías.

El problema con el que tengo problemas cada mes se compone de más días y estos días cambian cada año del calendario.

Gracias a todos por cualquier ayuda o dirección.

otra información: Máquina de Linux, haciendo uso de PHP y MySQL

Respuesta

19

En lugar de actualizar los recuentos por día, semana, etc. Sólo tiene que insertar una fila en una tabla cada vez que realiza una actividad como esta:

insert into activities (activity_date, activity_info) 
values (CURRENT_TIMESTAMP, 'whatever'); 

Ahora sus informes son muy simples como:

select count(*) from activities 
where activity_date between '2008-01-01' and '2008-01-07'; 

o

select YEARWEEK(`activity_date`) as theweek, count(*) 
group by theweek 
+1

¿Esta tabla no sería muy grande si, por ejemplo, las actividades que se registran ocurren cada vez que La página está cargada de un sitio web y hay muchos usuarios que tienen cuentas en este sitio web. – Abs

+1

Sí. Esto es con lo que deberías comenzar como un diseño inicial. La optimización puede venir más tarde, tal vez. – thomasrutter

+1

De acuerdo con Thomas. Además, observe la utilidad de esta información: puede responder muchas más preguntas de las que piensa actualmente, por ejemplo, número promedio de usuarios/período distintos, vistas de página promedio por usuario, ... Siempre puede archivar datos anteriores si el espacio se convierte en un problema. –

4

Puede simplemente agregar registros en la tabla y SELECT utilizando funciones de agregado.

Si por alguna razón usted necesita para mantener estadísticas agregadas, es posible utilizar:

CREATE TABLE aggregates (type VARCHAR(20), part VARCHAR(10) NOT NULL PRIMARY KEY, activity INT) 

INSERT INTO aggregates (type, part, activity) 
VALUES ('year', SUBSTRING(SYSDATE(), 1, 4), 1) 
ON DUPLICATE KEY UPDATE activity = activity + 1 

INSERT INTO aggregates (type, part, activity) 
VALUES ('month', SUBSTRING(SYSDATE(), 1, 7), 1) 
ON DUPLICATE KEY UPDATE activity = activity + 1 

INSERT INTO aggregates (type, part, activity) 
VALUES ('day', SUBSTRING(SYSDATE(), 1, 10), 1) 
ON DUPLICATE KEY UPDATE activity = activity + 1 

Esto actualizará automáticamente las filas existentes e insertar inexistente cuando sea necesario.

+0

¿Qué ocurre si el problema de actualización concurrente causa un valor incorrecto? – huuthang

3
  1. tabla de eventos: id, id de actividad, fecha y hora, ID de usuario.
  2. tabla de usuarios: id, nombre de usuario, etc.
  3. tabla de actividades: id, nombre de la actividad, etc

Sólo tienes que introducir una nueva fila en eventos cuando ocurre un evento. Luego puede analizar los eventos, pero manipulando hora, fecha, usuario, actividad, etc.

2

Para empezar, probablemente se imagine una sola tabla, ya que esta sería la forma más normalizada. La tabla simplemente tiene una entrada por cada golpe que recibe, con cada fila que contiene la fecha/hora de ese golpe.

Ahora, de esta manera, para obtener estadísticas de cada hora, día, semana, etc., las consultas son simples pero su base de datos tendrá que hacer un trabajo de consulta bastante pesado. En particular, las consultas que realizan sumas, recuentos o promedios necesitarán obtener todas las filas relevantes.

Puede evitar esto al calcular previamente los recuentos necesarios en una segunda tabla, y asegurarse de sincronizar esa tabla con la primera con regularidad. El problema es que usted será responsable de mantener ese caché sincronizado usted mismo.

Esto probablemente implicaría hacer una fila por cada hora.Todavía será mucho más rápido hacer una consulta por un día, o un mes, si solo está obteniendo un máximo de 24 filas por día.

Su otra sugerencia fue agregarlo desde el principio, nunca almacenando cada hit como una fila. Probablemente lo haga, como antes, con una fila por cada hora. Cada golpe aumentaría la fila de las horas relevantes por uno. Solo tendrías los datos en una ubicación, y ya estaría bastante bien resumida.

La razón por la que sugiero por hora en lugar de por día, es que esto todavía le da la opción de admitir varias zonas horarias. Si su granularidad es solo diaria, no tiene esa opción.

1

La respuesta de Tony Andrews es la más simple; sin embargo, algunas veces se usa una estructura de copo de nieve en las aplicaciones de data warehouse: una tabla que cuenta todas las actividades, otra para actividades diarias, otra para actividades mensuales y una tercera para actividades año. Con este tipo de estructura, la actividad entre dos fechas cualquiera se puede calcular de manera muy eficiente. https://en.wikipedia.org/wiki/Snowflake_schema

1

Utilice un diseño de esquema en estrella. (o tal vez un diseño de copo de nieve).

Star-Schema Design

que va a terminar haciendo una inserción en una tabla de hechos para cada nueva actividad. Vea la sugerencia de Tony.

Necesitará al menos dos tablas de dimensiones, una para usuarios y otra para marcos de tiempo. Probablemente habrá dimensiones para el tipo de actividad, y tal vez incluso para la ubicación. Depende de lo que quieras hacer con los datos.

Su pregunta está relacionada con la tabla de dimensiones de los cuadros de tiempo. Vamos a llamarlo "Almanaque". Elija una granularidad. Digamos el día. El almanaque tendrá una fila por día. La clave principal puede ser la fecha. Su tabla de hechos debe incluir esta clave principal como clave externa para facilitar las uniones. (No importa si lo declara o no como una clave externa. Eso solo afecta la integridad referencial durante el proceso de actualización).

Incluya columnas en el Almanaque para cada período de informe que pueda imaginar. Semana, mes, trimestre, año, etc. Incluso puede incluir períodos de informes relacionados con el calendario de su empresa.

Aquí hay un artículo que compara ER y DM. Soy inusual en que me gustan ambos métodos, eligiendo el método apropiado para la tarea apropiada.

http://www.dbmsmag.com/9510d05.html

0

Su pregunta se refiere a la tabla de dimensiones marcos de tiempo. Vamos a llamarlo "Almanaque". Elija una granularidad. Digamos el día. El almanaque tendrá una fila por día. La clave principal puede ser la fecha. Su tabla de hechos debe incluir esta clave principal como clave externa para facilitar las uniones. (No importa si lo declara o no como una clave externa. Eso solo afecta la integridad referencial durante el proceso de actualización)

Cuestiones relacionadas