2010-11-08 9 views
10

Mi pregunta es sobre la desnormalización. En una base de datos, ¿cuándo debe almacenar datos derivados en su propia columna, en lugar de calcularlos cada vez que los necesite?En una base de datos, ¿cuándo debe almacenar los datos derivados?

Por ejemplo, supongamos que tiene Usuarios que reciben votos a favor por sus preguntas. Muestra la reputación de un usuario en su perfil. Cuando un usuario está upvoted, en caso de que incrementas su reputación, o en caso de que calcularlo cuando recupera su perfil:

SELECT User.id, COUNT(*) AS reputation FROM User 
LEFT JOIN Question 
    ON Question.User_id = User.id 
LEFT JOIN Upvote 
    ON Upvote.Question_id = Question.id 
GROUP BY User.id 

Cómo uso intensivo del procesador que hace la consulta para obtener la reputación de un usuario tiene que ser antes de que valdría la pena mantener un seguimiento de forma incremental con su propia columna?

Para continuar nuestro ejemplo, supongamos que un voto a favor tiene un peso que depende de la cantidad de votos a favor (no de la cantidad de reputación) que tiene el usuario que lo emitió. La consulta para recuperar su reputación de repente explota:

SELECT 
    User.id AS User_id, 
    SUM(UpvoteWeight.weight) AS reputation 
FROM User 
LEFT JOIN Question 
    ON User.id = Question.User_id 
LEFT JOIN (
    SELECT 
    Upvote.Question_id, 
    COUNT(Upvote2.id)+1 AS weight 
    FROM Upvote 
    LEFT JOIN User 
    ON Upvote.User_id = User.id 
    LEFT JOIN Question 
    ON User.id = Question.User_id 
    LEFT JOIN Upvote AS Upvote2 
    ON 
     Question.id = Upvote2.Question_id 
     AND Upvote2.date < Upvote.date 
    GROUP BY Upvote.id 
) AS UpvoteWeight ON Question.id = UpvoteWeight.Question_id 
GROUP BY User.id 

Esto es mucho fuera de proporción con la dificultad de una solución gradual. ¿Cuándo valdría la normalización y cuándo los beneficios de la normalización se reducen a los beneficios de la desnormalización (en este caso, dificultad de consulta y/o rendimiento)?

Respuesta

4

¿Cuán intenso es el uso del procesador para obtener la reputación de un Usuario antes de que sea útil realizar un seguimiento incremental con su propia columna?

Realmente hay dos preguntas aquí en forma de una: (1) ¿Este cambio mejorará el rendimiento y (2) Vale la pena el esfuerzo?


En cuanto a si la mejora del rendimiento, esto es básicamente un análisis de pros y contras estándar.

Los beneficios de normalización son básicamente de dos tipos:

integridad
  • más fácil datos

  • No había problemas con re-cálculo (por ejemplo, si los cambios de datos subyacentes, la columna derivada necesita ser re -calculado).

Si cubre la integridad de los datos con una solución aplicarse con contundencia (por ejemplo gatillo, Sstored-proc-únicos cambios permanentes de datos con cambio de mesa directa revocados, etc ...), entonces esto se convierte en un cálculo directo de si el costo de verificar si el cambio en los datos fuente justifica el cálculo de los datos derivados vs.recalculando los datos derivados cada vez. (NOTA: Otro enfoque para mantener la integridad de los datos es forzar el recálculo de los datos derivados según lo programado, donde los datos pueden permitirse ser inexactos con cierta tolerancia de tiempo. StackExchange toma este enfoque con algunos de sus números).

En un escenario típico (muchos más datos recuperados y mucho menos cambios en los datos subyacentes), la matemática bastante obvia a favor de mantener los datos derivados des-normalizados en la tabla.

En algunos casos excepcionales en los que los datos subyacentes cambian MUY a menudo, sin embargo, los datos derivados no se recuperan con tanta frecuencia, lo que podría ser perjudicial.


Ahora, estamos en la cuestión mucho más importante: ¿La mejora del rendimiento valer la pena el esfuerzo?

Tenga en cuenta que, al igual que con todas las optimizaciones, la pregunta más importante es "es la optimización siquiera vale la pena en absoluto?", Y como tal es el sujeto a dos consideraciones principales:

  1. medición exacta diferencia de rendimiento y, en general, perfil.

  2. Contexto de esta optimización específica en la imagen completa de su sistema.

E.g. Si la diferencia en el rendimiento de la consulta - que como siempre al optimizar primero debe medirse - es 2% entre los datos derivados en caché y computados, la complejidad adicional del sistema en la implementación de la columna del caché de reputación puede no valer la pena en primer lugar. Pero lo que el umbral de cuidar y no preocuparse es en cuanto a la mejora marginal depende de la imagen general de su aplicación. Si puede tomar medidas para mejorar el rendimiento de la consulta en un 10% en un lugar diferente, concéntrese en eso frente al 2%. Si eres Google y el 2% adicional del rendimiento de la consulta tiene un costo de 2 mil millones de dólares en hardware adicional para soportarlo, debe optimizarse de todos modos.

1

Realmente no hay una respuesta clara porque depende de muchos factores como el volumen del sitio y la frecuencia con que muestra la reputación (es decir, solo en su página de perfil o junto a CADA instancia de su nombre de usuario, en cualquier lugar) La única respuesta real es "cuando se vuelve demasiado lento"; en otras palabras, probablemente necesitarías probar ambos escenarios y obtener algunas estadísticas de rendimiento del mundo real.

Personalmente me gustaría desnormalizar en esta situación particular y tener un desencadenador de inserción en la tabla de actualización o una consulta de actualización periódica que actualiza la columna de reputación denromalized. ¿Sería realmente ser el fin del mundo alguien dijo "204" en lugar de "205" hasta que la página se actualice?

0

Solo quería arrojar un nuevo ángulo sobre la preocupación por la integridad de los datos que DVK cubrió tan bien en la respuesta anterior. Piense si otros sistemas pueden necesitar acceder/calcular los datos derivados, incluso algo tan simple como un sistema de informes. Si otros sistemas necesitan usar el valor derivado o actualizar el valor de respuesta, entonces puede tener consideraciones adicionales sobre cómo reutilizar el código de cálculo o cómo asegurarse de que el valor derivado se actualice de manera constante, sin importar qué sistema cambie el voto a favor.

Cuestiones relacionadas