Esquema de la base de datos - información de corrección de rendimiento v


1

Tengo una base de datos que almacena información sobre los usuarios de mi sitio web (nombre de usuario, contraseña, etc.).También almaceno información sobre su actividad en el sitio.

Por ejemplo, tengo una gran cantidad de preguntas en mi sitio.Tengo algunos temas y cada tema tiene varias preguntas.

Cada vez que un usuario responde una pregunta, almaceno el resultado en una tabla que contiene las tuplas: (user_id, question_id, timesAnswered, timesCorrect)

También tengo una tabla llamada topics_and_questions contiene (question_id (PK), topic_id (PK)) que se puede usar para determinar a qué tema (s) pertenece la pregunta.

En base a lo anterior, es posible determinar cuántas preguntas ha respondido un usuario sobre un tema en particular.Sin embargo, esto implicaría buscar en la primera tabla todos los cuestionarios de respuesta respondidos por el usuario y luego buscar en la tabla topics_and_questions .(La primera mesa podría ser bastante grande)

¿Tiene sentido, en cambio, crear otra tabla users_and_topics que contenga (ID_usuario, ID de tema, preguntas respondidas) y actualizar esto cada vez que se responda una pregunta?Parecería que esta sería una mala práctica de la base de datos, ya que los datos se replicarían esencialmente (esta tabla se puede derivar de las tablas actuales).Sin embargo, podría proporcionar beneficios de rendimiento, ya que significaría menos trabajo para el servidor.Esperaría alrededor de 1 solicitud de esta información cada 5 minutos por usuario de mi sitio web.

Estoy usando innoDB, la base de datos MySQL si importa

0

Estoy de acuerdo con su especulación de que es una mala práctica de diseño.Lo recomiendo en contra.Cada vez que haces este tipo de cosas, casi inevitablemente vuelve a morder y la diferencia de rendimiento en comparación con un esquema adecuadamente diseñado debería ser pequeña.

Dice que tal como está ahora, su proceso "implicaría buscar en la primera tabla todas las preguntas y respuestas contestadas por el usuario, luego buscar en la tabla de temas y preguntas" pero eso no es realmente un buen análisis de lo que debería suceder detrás de escena.

Diseñado correctamente, este proceso implicaría revisar un índice en la primera tabla para todas las preguntas respondidas por el usuario, unirse a la segunda tabla para encontrar los temas de las preguntas (y posiblemente una tercera tabla para encontrar los nombres de los temas), pero Todo en una consulta y sin escaneos de tabla completa.

Si su primera tabla (no se proporcionó el nombre de la tabla) tiene (user_id, question_id) como su clave principal (como probablemente debería), entonces encontrar las preguntas respondidas por cada usuario será una operación rápida, sin importar cuántos registros haya en esta tabla .Las filas en InnoDB se almacenan en el orden de la clave principal, por lo que no es necesario "buscar" toda la tabla que debe suceder ... el motor de almacenamiento puede ir directamente a donde están los registros del usuario sin un análisis completo de la tabla.Si (user_id, question_id) no es la clave principal, entonces agregar un índice en (user_id, question_id) optimizará esta parte de la consulta.

En topics_and_questions o bien (question_id) o (question_id, topic_id) probablemente debería ser la clave principal, dependiendo de si una pregunta puede estar en varios temas.Si puede, por supuesto, entonces contar preguntas respondidas se vuelve más complicado.

Como parece que le está permitiendo a un usuario responder la misma pregunta más de una vez, es posible que haya otro problema a considerar: en realidad, tiene que duplicar parte de lo que está tratando de evitar, cada vez que actualice esta nueva tabla propuesta: Debe comprobar si la pregunta que se acaba de responder fue una que se respondió antes o no, y solo aumentar este contador, si es así, supongo.

  0

Gracias por la gran respuesta.Para aclarar, una pregunta puede tener varios temas y un usuario puede responder la misma pregunta más de una vez.Planeo verificar si el usuario ha respondido la pregunta anteriormente antes de agregar una nueva fila a la tabla 30 sep. 122012-09-30 22:21:32


0

Esta es una "vista materializada" y los activadores se usan a menudo para implementarlos.Es una duplicación de datos y una oportunidad de inconsistencia de datos, pero si es necesario y está bien implementado, pueden mejorar mucho el rendimiento.

Pero no veo lo que estás preguntando .


0

Según los números que proporcionó (1 solicitud por 5 minutos para 1 usuario), sugeriría usar el almacenamiento en caché en el lado de la aplicación en lugar de realizar la desnormalización.Siempre puede desnormalizar sus datos más tarde si decide que la base de datos es realmente un cuello de botella en el sistema.

Creo que no hay nada malo con el enfoque que desea implementar, pero la pregunta es si realmente lo necesita ... Pido disculpas si mi respuesta es demasiado amplia, pero no proporcionó ningún número (como el plan de ejecución actual,% de tales consultas en comparación con el número total de consultas en el sistema, plan de ejecución para las consultas que usarían un nuevo diseño de db, algún costo de refactorización del sistema actual, etc.).