Pregunta

Tengo una consulta algo compleja con múltiples subterías (anidadas), que quiero que pongan a disposición para los desarrolladores de aplicaciones. La consulta es genérica y genera una vista con valores calculados a través de una recopilación de conjuntos de datos, y se espera que el desarrollador solo necesite algunos registros de lo que la consulta devuelve (es decir, limitará el resultado para la identificación de alguna entidad o un rango de fechas o algunos tal).

Puedo ver 3 formas de implementar esto:

  1. Deje que los desarrolladores incorporen la consulta en cada aplicación y agregue la suya propia WHERE cláusulas según sea necesario.
  2. Cree un procedimiento almacenado que acepte como parámetros todas las condiciones que espero que los desarrolladores necesiten (en aras del argumento, digamos que puedo predecir lo que será necesario para el futuro previsible), y el procedimiento ejecutará la consulta compleja y la filtrará. De acuerdo con los parámetros pasados.
  3. Implemente la consulta como una vista con varias vistas (porque MySQL no permite las subteres en las vistas) y haga que los desarrolladores lo usen como una tabla y usan WHERE Para que cada solicitud aplique los filtros que necesitan. Actualmente estoy mirando 3 subvistas adicionales, principalmente porque algunas subteres se usan varias veces y las hacen como subvistas previenen la duplicación; de lo contrario, podría haber sido peor ;-).

¿Qué será mejor rendimiento? (Suponiendo que toda la indexación sea equivalente en todos los casos) Vaya a los peores escenarios, si es posible.

¿Qué será mejor en los términos de mantenimiento del código, crees?

¿Fue útil?

Solución

Me gustan las preguntas que definen "bien": ha preguntado específicamente sobre el rendimiento y la mantenibilidad, lo que permite respuestas para hablar sobre esa compensación.

Desde el punto de vista de rendimiento, no creo que haya ninguna diferencia entre las 3 opciones, siempre que las consultas y los datos se ajusten dentro de sus escenarios esperados. Probaría con 100 veces más datos y potencialmente ampliaría la cláusula "donde" para ver qué sucede, pero la estructura de indexación, etc. es más probable que afecte el rendimiento que si ejecuta el mismo SQL desde un proceso almacenado, a través de un ver, o desde una aplicación de cliente.

La mejor manera de responder a esa pregunta es probarla: por supuesto, hay muchos detalles específicos que podrían invalidar las respuestas generales de "esperaría X, Y o Z" que los desbordantes que pueden dar. Si el rendimiento es una preocupación crítica, use una herramienta de llenado de base de datos (Redgate Make On, he usado DBMonster en el pasado) y pruebe las 3 opciones.

Desde un punto de mantenimiento de, Ver, proporcionaría una opción 4, que, en mi opinión, es, con mucho, la mejor.

Opción 4: Cree una biblioteca de acceso a datos que encapsula el acceso a sus datos. Haga que la biblioteca exponga métodos y parámetros para refinar la selección de registros. Considere usar el patrón de especificación (http://en.wikipedia.org/wiki/specification_pattern). Use las consultas que sean mejores dentro de la biblioteca y no moleste a los desarrolladores con los detalles de implementación.

Si eso no funciona, un código de aplicación heterogéneo, un cambio demasiado cambio para un requisito simple, evaluaría las opciones de la siguiente manera:

  1. SQL incrustado: dependiendo de la cantidad de veces que se reutilice este SQL, esto puede estar bien. Si solo hay una parte del código que ejecuta el SQL, es lógicamente similar a la biblioteca de acceso a datos. Sin embargo, si el mismo fragmento necesita ser reutilizado en muchos lugares, es una fuente probable para errores: un pequeño cambio en el SQL necesitaría repetirse en varios lugares.

  2. Procedimiento almacenado: Generalmente no me gustan los procedimientos almacenados por razones de mantenimiento: tienden a ser frágiles mediante la carga excesiva y crean una forma de pensar de procedimiento. Por ejemplo, si tiene otros requisitos para usar este cálculo SQL en un procedimiento almacenado separado, muy rápidamente termina con un modelo de programación de procedimientos, con procesos almacenados que se llaman.

  3. Vistas: Esta es probablemente la mejor opción. Pone la lógica de datos específica en un solo lugar, pero promueve el uso de la lógica basada en establecimientos porque la ruta de acceso se realiza a través de una declaración selecta, en lugar de ejecutar declaraciones de procedimiento. Las vistas son fáciles de incorporar en otras consultas.

Otros consejos

Si se implementa bien, cualquiera de las tres soluciones estaría bien para la mantenimiento, pero tenga en cuenta cómo trataría a cada uno de ellos en un proceso de migración (migración de código o base de datos).

Si la consulta es grande, el procedimiento almacenado le dará un poco de extra actuación Debido a menos banda de banda, porque está enviando una consulta de menor tamaño. También puede obtener un poco de seguridad adicional con esta solución.

Para mantenimiento Solución, preferiría la primera y segunda solución, porque puede hacer cualquier cambio en la consulta sin hacer ningún cambio de base de datos. Si elige la primera solución, envolvería la llamada de consulta dentro de una función para que solo tenga un lugar para hacer cambios.

A partir de una punto de vista del desarrollador, Elegiría la solución de vista que Beacuse es la más transparente, quiero decir que es como consultar solo una tabla normal, puede verificar la estructura de la mesa con un comando de describir, o simplemente seleccionar los campos y condiciones que necesita consultar, o unirse con otra mesa, etc ...

Acerca de donde la flexibilidad de la cláusula, puede lograrlo con cualquiera de las soluciones propuestas. Puede agregar un parámetro Where en su función de envoltura (1), puede agregar un parámetro Where al procedimiento almacenado pero tener cuidado con las inyecciones (2), o el desarrollador puede agregar una cláusula WHERE como de costumbre con la vista (3)

Teniendo en cuenta que en las vistas de MySQL no son tablas temporales, Si la consulta es muy compleja Estas soluciones no serían las mejores si la consulta se usa mucho y de diferentes maneras (deshabilitando el impulso de rendimiento de caché). Consideraría una mesa temporal Solución (Tabla de contador) que se actualiza cada período de tiempo con una tarea programada / Cron (por ejemplo, un día, una semana, cuando sea necesario) o se actualiza configurando los desencadenantes PROPPER. Esta solución podría mejorar bastante el rendimiento.

Espero que esto ayude, me gusta más la solución View, pero tal vez sea más complejo desarrollar desde el punto de vista de una base de datos.

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