Pregunta

lo siento si el título no está muy claro. Voy a tratar de explicar ahora:

Tengo dos tablas: tablas A y B. La relación entre ellos es uno (para una mesa) a muchos (de la tabla B). Por lo tanto, es algo así como la situación maestro-detalle. Tengo una columna 'Cantidad' de la tabla B que es, obviamente, decimal y una columna 'TotalAmount' de la tabla A. Estoy tratando de ti encontrar la manera de mantener el valor en el cuadro A hasta la fecha. Mi sugerencia es hacer un punto de vista basado en el cuadro A con consulta de funciones agregadas contar las cantidades de la tabla B. Por supuesto, con los índices adecuados ... Sin embargo, mi compañero de equipo sugieren para actualizar el valor en el cuadro A cada vez que cambia algo en el cuadro B de nuestra aplicación. Me pregunto, ¿cuál será la mejor solución a este problema? Puede ser una tercera variante?

Algunas aclaraciones ... esperábamos esto mesas sean las tablas de más rápido crecimiento en nuestra base de datos. Y la tabla B va a crecer mucho más rápido que la tabla A. La operación más frecuente en el cuadro B será insert ... y casi nada más. La operación más frecuente en el cuadro A será de selección ... pero no sólo.

¿Fue útil?

Solución

Veo una serie de opciones:

  1. Utilizar un desencadenador de inserción en la tabla B y hacer las actualizaciones de la tabla A como su amigo sugiere. Esto mantendrá la tabla B lo más actualizada posible.
  2. Haga que un trabajo programado que actualiza la tabla A cada x minutos (x = lo que tenga sentido para su aplicación).
  3. Cuando la actualización de la tabla B, hacer una actualización de la tabla A en la lógica de la aplicación. Esto puede no funcionar si actualiza la tabla B en muchos lugares.

Otros consejos

Si usted tiene un lugar único en su aplicación donde se inserta nuevas filas a la tabla B, a continuación, la solución más sencilla es enviar un UPDATE A set TotalAmount=TotalAmount + ? where ID = ? y transmitir los valores que acabas de usar para insertar en B. Asegúrese de envolver ambas consultas ( el inserto y la actualización) en una transacción para que sea tanto suceda o ninguno.

Si eso no es sencillo, entonces su siguiente opción es un trigger. Lea la documentación para su base de datos la manera de crearlos. Básicamente un disparador es una pequeña pieza de código que se ejecuta cuando ocurre algo en el PP (en su caso, cuando alguien inserta los datos en el cuadro B).

La vista es otra opción, pero puede causar problemas de rendimiento durante selecciona qué encontrará difícil de resolver. Pruebe con un una "columna calculada" "vista materializada" o en su lugar (pero estos pueden causar problemas de rendimiento cuando inserción / extracción de columnas).

Si este valor se va a cambiar mucho, es mejor usar una vista: En definitiva, es la aplicación más segura. Pero aún mejor sería utilizar disparadores (si su base de datos compatible con ellas.)

Me imagino que su compañero sugiere actualizar el valor de cada inserto porque piensa que necesitará el valor con bastante frecuencia y que podría dar lugar a una ralentización recalcular el valor cada vez. Si ese es el caso:

  • Su base de datos debe hacerse cargo de la función de caché para esto probablemente no será un problema.
  • Si lo es, no obstante, se puede añadir esa característica en una etapa posterior -. De esta manera usted puede asegurarse de que su aplicación funciona de otra manera y tendrá un más más fácil el tiempo de depuración que la columna caché

Sin duda, recomendaría el uso de un disparador sobre el uso de la lógica de aplicación, como que asegura que la base de datos mantiene el valor hasta a la fecha, en lugar de confiar en todas las personas que llaman. Sin embargo, desde el punto de vista del diseño, me gustaría tener cuidado de no almacenar los datos generados en la misma mesa que los datos no genera - Creo que es importante mantener una separación clara, para que la gente no se confunda entre lo que los datos que deberían se mantiene y lo que se mantendrá para ellos.

Sin embargo, en general, prefieren vistas a disparadores - de esa manera usted no tiene que preocuparse por mantener el valor en absoluto. Perfil para determinar si el rendimiento es un problema. En Postgres, creo que incluso se podría crear un índice en los valores calculados, por lo que la base de datos no tendría que mirar la tabla de detalles.

La tercera forma, volver a calcular periódicamente, será mucho más lento que los factores desencadenantes y probablemente más lento que una vista. Que no es apropiado para su uso de todos modos es la guinda del pastel:.)

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