¿Cuándo debo usar los procedimientos almacenados?

19

Si tengo toda mi lógica de negocios en código y hago uso de Entity Framework, ¿en qué situaciones (si las hubiera) sería mejor mover algo de lógica de negocios a un procedimiento almacenado, en lugar de mantenerlo todo en código?

Para ser claros, quiero decir en conjunto con la configuración actual (lógica de negocios en el código), no en lugar de. He visto una serie de preguntas similares que preguntan por los pros y los contras de tener toda la lógica de negocios en los procedimientos almacenados, pero no he encontrado mucho sobre el uso de los procedimientos almacenados con moderación para la lógica de casos límite, mientras mantengo el resto de la lógica de negocios en codigo.

Si hace la diferencia, estoy usando MSSQL y Entity Framework.


Estas son las situaciones en las que he usado procedimientos almacenados antes:

  • Un informe complicado que tardó minutos en ejecutarse (esta era una página en una aplicación web). Descubrí que podía escribir SQL que era mucho más eficiente (solo tomaba unos segundos en ejecutarse) que lo que LINQ estaba proporcionando.
  • Una aplicación web necesitaba leer y escribir en algunas tablas en una base de datos separada que contenía mucha otra información confidencial que era irrelevante para la aplicación. En lugar de darle acceso a todo, utilicé un procedimiento almacenado que solo hace lo que se necesita y solo devuelve información limitada. La aplicación web podría tener acceso únicamente a este procedimiento almacenado, sin acceso a ninguna tabla, etc.

Otras publicaciones que he visto antes de hacer esta pregunta:

Amy Barrett
fuente
44
Ambas situaciones son razones perfectamente legítimas para escribir procedimientos almacenados. ¿Estás preguntando por qué son legítimos?
Robert Harvey
@RobertHarvey Me estaba asegurando de que fueran legítimos y estaba buscando otros escenarios o razones por las que podría hacer una excepción y escribir un procedimiento almacenado en lugar de mantenerlo en el código.
Amy Barrett
Haría una excepción y escribiría un procedimiento almacenado cuando determine que resuelve un problema mejor que las otras técnicas disponibles, que es exactamente lo que hizo.
Robert Harvey

Respuestas:

10

Ya tienes un par de escenarios perfectamente buenos.

Hay muchas otras razones también. EF es realmente bueno en CRUD y en informes bastante directos. Sin embargo, a veces, EF no es la herramienta perfecta. Algunas otras razones (escenarios) para considerar el uso de procedimientos almacenados en combinación con Entity Framework incluirían:

  • Tiene unidades de trabajo complejas, que tal vez involucran muchas tablas, que no pueden integrarse fácilmente en una transacción utilizando las funciones de EF.
  • Su base de datos no funciona bien con EF porque no aprovecha la integridad referencial declarativa (restricciones de clave externa). Este suele ser un mal escenario para encontrarse, pero a veces hay escenarios apropiados, como bases de datos utilizadas para procesos ETL.
  • Debe trabajar con datos que cruzan los límites del servidor con servidores vinculados.
  • Tiene escenarios de recuperación de datos muy complejos en los que se necesita SQL "bare metal" para garantizar un rendimiento adecuado. Por ejemplo, tiene combinaciones complejas que necesitan sugerencias de consulta para funcionar bien en su situación específica.
  • Su aplicación no tiene permisos CRUD completos en una tabla, pero se puede permitir que su aplicación se ejecute en un contexto de seguridad en el que confía su servidor (identidad de la aplicación, en lugar de la identidad del usuario, por ejemplo). Esto puede surgir en situaciones en las que los DBA restringen el acceso a la tabla a los procesos almacenados solo porque les da un control más granular sobre quién puede hacer qué.

Estoy seguro de que hay muchos más además de estos. La forma de determinar el mejor camino hacia adelante en cualquier circunstancia particular es usar un poco de sentido común y enfocarse en el objetivo principal, que debe ser escribir código de alta calidad y fácil de mantener. Elija las herramientas que le dan este resultado en cada caso.

Joel Brown
fuente
Gracias Joel, has mencionado algunos otros escenarios en los que no había pensado.
Amy Barrett
Buena respuesta. Sin embargo, me pregunto si tiene muchos usuarios conectados a la base de datos y ejecutando consultas complicadas o procedimientos almacenados, ¿no terminará poniendo mucha carga en el servidor de la base de datos?
Ripal Barot
1
@RipalBarot No hay duda de que cuanto más ocurra con la carga de trabajo (más usuarios, consultas más complejas), más serán las demandas de su servidor de base de datos. Sin embargo, una cosa a tener en cuenta es que el uso de procedimientos almacenados en lugar de ORM como Entity Framework a menudo puede disminuir la carga de trabajo (comparativamente) porque los procedimientos almacenados pueden tener planes de consulta precompilados. Cuando una consulta proviene de un ORM, el DBMS a menudo tiene que comenzar a determinar cómo manejar la consulta. Cuando llama a un procedimiento almacenado equivalente, la base de datos ya sabe cómo cumplirlo de manera eficiente.
Joel Brown el
2

Quizás tenga sentido, dar vuelta la pregunta y encontrar casos de uso donde solo los procedimientos almacenados puedan hacer, lo que desea lograr. Quizás haya casos de uso en los que se destaquen los procedimientos almacenados.

Si hace la diferencia, estoy usando MSSQL y Entity Framework.

Mi conocimiento sobre EF es limitado, pero hasta donde puedo ver, EF es ( solo ) un ORM como cualquier otro; y afortunadamente es capaz de usar SQL sin formato .

Si tomo tus dos puntos principales:

Un informe complicado que tardó minutos en ejecutarse (esta era una página en una aplicación web). Descubrí que podía escribir SQL que era mucho más eficiente (solo tomaba unos segundos en ejecutarse) que lo que LINQ estaba proporcionando.

LINQ / EF se estaba quedando corto cuando hacía un informe. Y como notaron, fue SQLmucho más rápido que usar un ORM. ¿Pero habla esto a favor de los procedimientos almacenados o solo en contra de usar el ORM para todo?

Su problema obviamente podría resolverse con SQL . Si esa consulta se almacenó y la versión controlada en su base de código hace, según su ejemplo, al menos no hay diferencia .

Una aplicación web necesitaba leer y escribir en algunas tablas en una base de datos separada que contenía mucha otra información confidencial que era irrelevante para la aplicación. En lugar de darle acceso a todo, utilicé un procedimiento almacenado que solo hace lo que se necesita y solo devuelve información limitada. La aplicación web podría tener acceso únicamente a este procedimiento almacenado, sin acceso a ninguna tabla, etc.

Lo mismo aquí: una cadena de conexión simple y una ACTUALIZACIÓN y su problema está solucionado. Este problema podría resolverse incluso con un ORM : simplemente use un servicio web frente a la otra base de datos y se logra la misma compartimentación / aislamiento .

Así que no hay nada que ver aquí.

Mirando algunos puntos que otros han hecho:

Tiene unidades de trabajo complejas, que tal vez involucran muchas tablas, que no pueden integrarse fácilmente en una transacción utilizando las funciones de EF.

Pero SQLpuede hacer eso. No hay magia involucrada aquí.

Su base de datos no funciona bien con EF

Nuevamente: use EF cuando sea apropiado.

Debe trabajar con datos que cruzan los límites del servidor con servidores vinculados

No veo cómo ayudan los procedimientos almacenados. Entonces no puedo ver una ventaja de los procedimientos almacenados; pero tal vez alguien arroje algo de luz sobre eso.

Tiene escenarios de recuperación de datos muy complejos en los que se necesita SQL "bare metal" para garantizar un rendimiento adecuado

De nuevo: "Límites de EF ".

Su aplicación no tiene permisos CRUD completos en una tabla, pero se puede permitir que su aplicación se ejecute en un contexto de seguridad en el que su servidor confía

Bueno. Voy con un tal vez .

Hasta ahora solo se hizo medio punto a favor de los procedimientos almacenados.


Quizás haya consideraciones de rendimiento, que hablan a favor de los procedimientos almacenados.

1) El almacenamiento de consultas tiene el beneficio de una simple llamada al procedimiento almacenado que encapsula la complejidad. Como el planificador de consultas conoce la consulta, es "más fácil" optimizarla. Pero los guardados son con el actual sofisticado planificador de consultas _minimal.

Además de eso, incluso si hay un pequeño costo al usar consultas ad hoc , si sus datos están bien estructurados e indexados cuidadosamente, la base de datos es simplemente el cuello de botella de su aplicación. Entonces, incluso si hay un pequeño delta, es despreciable considerando otros factores.

2) Sin embargo, se argumentó para almacenar consultas complejas en un DB. Hay dos cosas a considerar:

a) las consultas complejas hacen un uso masivo de la infraestructura de base de datos, lo que aumenta los tiempos de respuesta para cualquier otra consulta. No puede ejecutar muchas consultas costosas en paralelo . Esto no habla de procedimientos almacenados a favor o en contra , sino contra consultas complejas .

b) Si la consulta lleva tiempo de todos modos, ¿por qué molestarse con pequeñas victorias de velocidad de un procedimiento almacenado?

tl; dr

Nada habla directamente en contra de los procedimientos almacenados. Entonces, usar procedimientos almacenados está bien, si te hace feliz.

Pero por otro lado: no podría imaginar un caso de uso adecuado que hable inequívocamente a favor.

¿Cuándo debo usar los procedimientos almacenados?

La respuesta correcta es: cuando quieras . Pero hay otras opciones.

Thomas Junk
fuente
0

Para su caso específico, dado que está utilizando el marco de la entidad, se debe considerar el uso de procedimientos almacenados cuando el marco de la entidad no cumple con un requisito o inquietud.

El marco de la entidad hace un trabajo decente y el rendimiento será cercano o igual al uso de procedimientos almacenados. Eligió el marco de la entidad porque no quería preocuparse por SQL y dejará que el marco genere el SQL por usted.

Pero puede haber un caso marginal en el que el marco de la entidad se queda corto y no puede satisfacer sus necesidades. En este caso, uno escribiría el SQL a mano usando un procedimiento almacenado o una consulta parametrizada y luego usaría el marco de la entidad para llamar directamente a ese procedimiento almacenado / instrucción SQL.

Por lo tanto, no movería nada a un procedimiento almacenado a menos que el marco que se está empleando no pueda cumplir con el requisito.

Creo que lo peor que puede suceder es que uno elija usar el marco de la entidad y luego escriba todos los procedimientos almacenados. Ahora uno tiene una capa adicional que no agrega valor.

Jon Raynor
fuente
100% de acuerdo con el último párrafo
Ewan
0

Tener una necesidad técnica no es la opción más probable. Los programadores prefieren sus herramientas y generalmente se adaptan mejor para resolver sus problemas con ellas. Poner lógica en un sproc será la excepción. Deben considerarse la deuda técnica y los futuros desarrolladores que tienen que tomarse el tiempo para trabajar con una excepción. Puede haber un aumento de rendimiento en su RDBMS particular que es más fácil de implementar en un sproc o incluso en otro objeto db como una vista indizada.

Habrá momentos en los que necesite datos de una base de datos y simplemente no pueda obtenerlos del código de su aplicación. En muchas situaciones de grandes empresas / empresas, las necesidades comerciales pueden superar el alcance del Departamento de TI. Las empresas se compran y venden y sus aplicaciones van y vienen con ellas. A las agencias reguladoras y a los bancos no les importa si no puedes construir tu aplicación altamente escalable y bellamente codificada. Pueden dificultarle la vida al negocio, por lo que debe hacerlo.

Me he encontrado con situaciones en las que las aplicaciones de terceros o las herramientas de redacción de informes no le permiten acceder a su código. Sin código fuente abierto, sin API, sin interfaz web y sin servicios. Lo único que tienen es su propia herramienta especial de redacción de informes que solo funciona con objetos de base de datos: tablas, vistas, sprocs, funciones definidas por el usuario, etc. Usted pone la lógica donde sea que pueda acceder.

Si tiene un DBA que es muy bueno para escribir procedimientos almacenados, puede aprovechar ese talento en algunas situaciones. Es posible que desee activar una copia de seguridad desde su aplicación porque va a hacer un cambio importante de datos, entonces, ¿por qué no usar lo que usa su dba?

Algunas solicitudes Ad hoc son más fáciles de escribir un proceso hasta que pueda obtener toda la funcionalidad en su aplicación. Lo odiamos Retrocedemos, pero el espectáculo debe continuar.

JeffO
fuente
0

Recomiendo encarecidamente que no se coloque ninguna lógica comercial en un procedimiento almacenado. Sin embargo, puede haber un caso (usted enumeró dos buenos ejemplos) en el que es preferible colocar allí la lógica de acceso a datos .

En términos generales, si siente la tentación de usar SP, es una señal (un olor a código) que sugiere que su modelo de datos no se adapta bien a sus necesidades.

Editar: cuando los desarrolladores me preguntan sobre la lógica de acceso a datos / negocios, digo que la lógica de negocios se trata de cómo se comportan e interactúan los datos, mientras que la lógica de acceso a datos se trata de cómo se almacenan y recuperan los datos.

Por ejemplo: en su modelo de dominio, puede tener las entidades "Estudiante" y "Profesor", ambas derivadas de "Persona". (No digo que esto sea preferido, solo un ejemplo). Esto se puede almacenar en una base de datos relacional como una, dos o tres tablas. La elección depende de cuántas propiedades compartan y de los requisitos de rendimiento de lectura / escritura.

En la lógica de negocios, no debería importar cómo se almacenan esas entidades. (o si residen en un RDB) La lógica de acceso a datos se trata de cómo se almacenan físicamente.

Entonces, con respecto a la pregunta original: si un procedimiento almacenado hace que el almacenamiento y la recuperación de datos sean más eficientes (o más robustos), tiene un caso. Si el procedimiento almacenado es simplemente para imponer una regla que sea válida independientemente de cómo se almacenen los datos, evítelo. Hace que su código esté más estrechamente acoplado a la base de datos.

Guran
fuente
2
¿Cómo definirías la lógica empresarial y la lógica de acceso a datos ?
Amy Barrett
@AmyBarrett: lógica de negocios , capa de acceso a datos .
Robert Harvey
@RobertHarvey Gracias por los enlaces. ¿La capa de acceso a datos es igual a la lógica de acceso a datos? Pregunto, ya que no parece haber mucha lógica real involucrada en la capa de acceso a datos, solo operaciones simples de CRUD.
Amy Barrett
@AmyBarrett: Bueno, a veces escribes métodos personalizados en la capa de acceso a datos, por lo que no siempre es CRUDO.
Robert Harvey
@RobertHarvey ¿No pertenecerían esos métodos personalizados a la capa de lógica empresarial?
Amy Barrett
-4

Creo que hay tres problemas aquí.

  1. La lógica de negocios en SQL es mala. Incluso si se ejecuta más rápido individualmente, no escala.

  2. Tradicionalmente, los SPROC siempre deben usarse para todo el acceso a datos como una capa de abstracción. Permitir que un DBA introduzca cambios en el rendimiento u otros cambios de la capa de datos sin afectar las aplicaciones consumidoras.

  3. EF no juega bien con sprocs. Perderá muchas de las 'buenas' características y ganancias de productividad al cambiar de la generación dinámica de consultas de Linq.

Entonces mi consejo general sería

  • Use SPROCs para todas las consultas SQL,

  • No pongas lógica empresarial ni ningún tipo de bucles en ellos,

  • No uses EF.

Ewan
fuente
Debido a que todo el SQL se ejecuta en el servidor db, solo puede escalar con dbs adicionales en lugar de cuadros de cálculo adicionales.
Ewan
1
Veo. Pero entonces el punto # 1 es puramente sobre una compensación entre dos problemas de rendimiento. Pero habrá momentos en que la solución SQL sea una clara victoria en términos de rendimiento, por lo que no veo cómo puede considerarse categóricamente "mala" sobre esta base.
1
Digamos que tiene un servicio web que hace un cálculo. Puedes hacerlo en código o en el sql. digamos que el sql es más rápido en una prueba de cabeza a cabeza de un solo cálculo. Pero cuando se maximiza el servicio de la CPU, es muy barato y fácil agregar un segundo, tercero, cuarto ... cuadro que ejecuta el servicio web pero difícil y costoso agregar una segunda base de datos replicada
Ewan
1
ese es un ejemplo de un escenario particular donde SQL puede ser un mal diseño debido a la escalabilidad. Pero incluso entonces no está claro: depende del número esperado de usuarios, el costo relativo de realizar el cálculo en la base de datos en comparación con el exterior, y así sucesivamente. Por supuesto que tienes razón en algunos casos, simplemente no creo que sea una regla universal.
3
Este es un mal consejo, en general. Hay muchas opciones para el acceso a datos que tienen ventajas sobre los procedimientos almacenados de codificación manual y funcionan igual de bien. Puede ejecutar sprocs directamente desde EF; de hecho, puede ejecutar cualquier consulta SQL directamente desde EF. Parte de la lógica empresarial funciona mejor en un servidor de base de datos, por lo que no puede declarar categóricamente que está prohibido allí. Los mapeadores relacionales de objetos son una herramienta del 80%; nunca tuvieron la intención de reemplazar completamente sus procesos de acceso a datos. Utilice procedimientos almacenados para lo que están destinados a ser utilizados: el 20% que un ORM no funciona bien.
Robert Harvey