stored-procedures business-logic

stored procedures - Argumentos a favor/en contra de la lógica de negocios en procedimientos almacenados



stored-procedures business-logic (16)

¿Cuáles son los argumentos a favor y en contra de la lógica comercial en los procedimientos almacenados?


"No se puede integrar en el control de origen muy fácilmente". - Si coloca el código que crea el proceso almacenado en un script que está controlado por la versión, esa objeción desaparece. Si sigues las ágiles ideas de la base de datos de Scott Ambler, eso es exactamente lo que deberías hacer.

No todos los desarrolladores son buenos modeladores de datos. Puedo pensar en esquemas horribles creados por desarrolladores que pensaban que un conocimiento de SQL les hacía expertos en bases de datos. Creo que hay mucho valor para que los desarrolladores trabajen con DBA y modeladores de datos.

Si solo una aplicación usa la base de datos, diría que la lógica empresarial puede aparecer en el nivel medio. Si muchas aplicaciones comparten la base de datos, quizás sea mejor colocarla en la base de datos.

SOA ofrece un camino intermedio: los servicios poseen sus datos. Solo el servicio tiene acceso a los datos; llegar a los datos significa pasar por el servicio. En ese caso, es posible poner las reglas en cualquier lugar.

Las aplicaciones van y vienen, pero los datos permanecen.


+: El servidor SQL a veces optimiza el código

+: Te obligan a pasar parámetros, lo que limita los problemas de inyección SQL

-: tu código depende de una única base de datos (algunos dbs ni siquiera tienen SP)

-: Para cambiar el código, debe conectarse a la base de datos

-: La lógica no está bien organizada

Personalmente, estoy en contra, pero tuve que usarlo una vez en un sitio web realmente ocupado. Usar SP en MS SQL trajo enormes beneficios, pero una vez que implementé el almacenamiento en caché, esos beneficios ya no eran tan grandes.


@Nick "Estoy totalmente en contra de eso. Una de las razones más importantes es la primera razón por la que earino declaró: vive en un lugar. No se puede integrar fácilmente en el control de la fuente. Es casi imposible tener dos desarrolladores trabajando en una procedimiento almacenado al mismo tiempo ".

No es que esté argumentando para poner la lógica comercial en los procedimientos almacenados (todo lo contrario). Pero estas razones que presentas no tienen sentido. Un procedimiento almacenado es simplemente un artefacto sql / DDL que se puede almacenar en el control de origen, y que también es un artefacto de despliegue (es decir, algo entregado al dba para su despliegue, de la misma forma que entregaría su guerra / oreja artefactos a los enlaces de TI / implementación) Uno o más desarrolladores pueden trabajar en el mismo procedimiento almacenado fuera del control de código fuente de la misma forma que lo haría con el código fuente anterior simple: mediante bifurcación, control de versiones y fusión.

Ahora, si la única copia del procedimiento almacenado (y los paquetes que los contienen) solo existe en la base de datos, entonces obviamente no puede controlar eso con el control de origen (y todos los problemas asociados a eso). Sin embargo, ese no es un problema de procedimiento almacenado sino un problema de ineptitud con respecto a cómo usar ese código. Es igualmente una muestra de ineptitud ya que solo una copia de su código fuente está en producción.

Trabajé en sistemas con cantidades masivas de código, tanto Java como PLSQL / DDL, y todos fueron versionados en clearcase. Todos fueron tratados como código fuente que sería compilado e implementado con un proceso estricto, con diferentes equipos trabajando en ellos. Nunca tuve ningún problema como lo que está describiendo.

Existen razones específicas del contexto para no poner la lógica comercial en los procedimientos almacenados, pero estos no son válidos.


Algunos pensamientos: tenga en cuenta que esta es una respuesta centrada en Java, pero es la mayor parte de mi experiencia reciente (últimos 10 años)

(1) Desarrollo concurrente por un (gran) equipo de desarrolladores. Si su aplicación es lo suficientemente compleja como para que cada desarrollador no pueda configurar su propia versión privada del DB (con enlaces atendidos / ref data / etc ...) es muy difícil tener todo un EQUIPO de desarrolladores trabajando en el mismo conjunto de paquetes PL-SQL (por ejemplo) al mismo tiempo almacenados en un DB DEVL compartido? Luego, su (experiencia) trabada en una base de datos con procedimientos no válidos / falta de coincidencia de código en las tablas a medida que las personas realizan cambios ...

Como arquitecto de Java, creo que es mucho más fácil que cada desarrollador tenga una instancia privada de JBoss en su escritorio y trabaje fácilmente en su propio conjunto de funcionalidades, e integre a su propio ritmo sin impactar a todos los demás ... lo que me atrae. ..

(2) Conjuntos de herramientas de integración continua. Aunque existen algunos ''conceptos'' similares en el mundo DB, mi experiencia me ha demostrado que el combo de (estoy escogiendo mis mejores favs actuales aquí):

  • mvn - sistema de construcción
  • junit - prueba unitaria automatizada
  • nexus - gestor de repo (gestiona la versión del ciclo de vida del artefacto, instantáneas y lanzamientos)
  • hudson - servidor de compilación ci
  • sonar - herramienta de análisis estático / informes de cobertura de código / MUCHO más

Ejecutar un proyecto grande usando todo lo anterior (herramientas gratuitas) permite una forma consistente / fácil de entregar XP a las masas y aplicar controles de calidad sobre todo el personal de TI. Oracle / PL-SQL no tiene los conjuntos de herramientas para hacer coincidir

(3) tools / libraries / etc ... Java tiene acceso a un increíble conjunto de servicios que otras plataformas no pueden tocar, algunos gratuitos y otros no. incluso los básicos, como log4j (sí lo tienen para PL / SQL, pero puzzles ... no es lo mismo) permite cosas como permitir a los desarrolladores crear registros ajustables de forma flexible que se pueden cambiar sobre la marcha (perfecto para el doblaje) . Documentación de API automatizada (a través de javadoc). Informes de cobertura de pruebas unitarias automatizadas. IDE increíbles (Eclipse) con depuradores integrados / autodespliegue a servidores de aplicaciones. Una API para interactuar con todos los tipos de servicios bajo el sol, bibliotecas de código abierto para hacer NADA y 100% de soporte por cada proveedor

(4) reutilización de servicios. lo que alguien comentó fue verdad. Si tiene reglas comerciales basadas en datos pesados, puede argumentar que estas deberían vivir en la capa DB. ¿Por qué? para evitar que todos los niveles intermedios tengan que duplicar esa lógica.

Pero lo mismo puede decirse de las reglas comerciales que no están basadas en datos o son suficientemente complejas como para que OO sea una opción más natural . Si pega TODA la lógica comercial en la base de datos, entonces están disponibles solo a través de la base de datos.

  • ¿Qué sucede si quiere que la validación se realice en el nivel del cliente o de la aplicación media y guardar un viaje de ida y vuelta al DB?
  • ¿Qué sucede si desea almacenar en caché solo los datos en el nivel intermedio (para el rendimiento) y las reglas de negocio se ejecutan contra los datos en caché?
  • ¿Qué sucede si tiene un servicio de nivel medio que no requiere acceso a BD, o tiene un cliente que puede proporcionar sus propios datos?
  • ¿Qué pasa si la porción dependiente de datos de las reglas comerciales necesita acceder a servicios externos? Luego terminas con una lógica empresarial fragmentada que se ve así:

yo

retCode = validateSomeDate(date); if (retCode == 1) then evaluateIfCustomerGetsEmail(...)//probably more stored proc invocations here... sendEmailMsg(....) else if (retCode == 2) then performOtherBizLogicStuf(...) //again, may need data, may not need data triggerExternalsystemToDoSomething(...) //may not be accessible via PL/SQL fi

Estoy seguro de que todos hemos visto sistemas escritos como el anterior y tuvimos que depurarlos a las 2 AM. Es extremadamente difícil tener una sensación coherente de un proceso complejo cuando la lógica empresarial está fragmentada entre niveles y, en algunos casos, es imposible de mantener.


DBMS! = Servidor de aplicaciones

  • Programación funcional (procedimiento almacenado DB) vs OOP. Para grandes programas, OOP es estándar.
  • IDE - eclipse, intellij, netbeans con todos los complementos para la depuración, prueba y análisis funciona solo con lenguajes de programación reales. Herramientas de código estático .
  • Control de versiones si obtienes uno para PLSQL & co. es genial. Si obtiene "sincronizar vista" directamente de usted IDE - usted es el verdadero afortunado.
  • Escala tu sistema. Para DB el sistema es el infierno. Necesita hardware costoso para otros "nodos". Replicación. Y probablemente una licencia para cada nodo. No olvide que todavía está en "programación funcional" y el esfuerzo por comprender y mantener dichos sistemas es mucho más grande.
  • Estás atascado con tu DB, intenta cambiar o agregar uno nuevo de otra compañía
  • Y así...

El procedimiento almacenado para la lógica de negocios hoy es una mala práctica. Use la arquitectura de 3 niveles en su lugar.


El rendimiento se mejorará enormemente al mover la lógica a los procesos almacenados, especialmente si se trata de transacciones explícitas.

En mi experiencia, los desarrolladores de aplicaciones no son muy buenos para escribir código de base de datos optimizado, y no tienden a pensar en concurrencia o problemas de rendimiento.
Si la lógica empresarial se mantiene en la capa de aplicación, tiende a tener que desplazar grandes cantidades de datos (a menudo en muchos viajes redondos) a través de la red, duplicarla en la memoria en el servidor DB y al menos una vez en el servidor de la aplicación. y haga una carga de procesamiento de fila por fila en la aplicación mientras mantiene abierta una transacción. Luego, los desarrolladores de la aplicación se quejan de que la base de datos es lenta y mantiene el bloqueo.

Si coloca la lógica en el DB donde sea posible, tiende a pasar solo unos pocos parámetros a través de la red, las transacciones no se mantienen mientras espera los recursos de la red, y todo funciona como un rayo engrasado. Las bases de datos deberían, por supuesto, ir al control de la fuente como cualquier otro código fuente. Hay muchas herramientas para eso.


Estoy completamente en contra de eso. Una de las principales razones es la primera razón por la que earino declaró: vive en un solo lugar. No se puede integrar en el control de fuente muy fácilmente. Es casi imposible tener dos desarrolladores trabajando en un proceso almacenado al mismo tiempo.

Mi otra queja principal es que SQL no es muy bueno para representar una lógica compleja. No tiene ningún concepto de alcance, el código tiende a copiarse porque existe una menor capacidad para reutilizar el código (a diferencia de un lenguaje OO).

Tienes que dar acceso a los desarrolladores a la base de datos para desarrollar allí. En muchas organizaciones, he trabajado en la información de que las personas están en un mundo diferente al de los desarrolladores, con diferentes permisos, etc. Mantener a los desarrolladores fuera de la base de datos en estos casos sería más difícil.


Hay diferentes tipos de "lógica de negocios". Considere la partición en función de cómo se relaciona con otras capas o servicios. Aquí hay algunas reglas generales desde una perspectiva de MVC:

a) En la base de datos (procedimiento almacenado) si está principalmente relacionado con los datos, y se puede hacer con combinaciones y cláusulas WHERE y SELECT relativamente simples.

b) En el controlador si está relacionado principalmente con el enrutamiento o el envío; es decir, control de flujo de IU a gran escala en términos de selección de pantalla o recurso.

c) En el modelo o modelo de vista si se trata de cálculos complejos y / o condicionales.

d) En la vista (como Razor) si se trata principalmente de un problema de visualización, como el formateo "amigable" y relativamente fácil de implementar. (Si es complejo, considere ponerlo en un modelo de vista).


Hay un dicho...

Cuando todo lo que tienes es un martillo, todo parece un clavo.

En mi humilde opinión, no hay una sola respuesta que se ajuste a todas las circunstancias. Me parece que muchas personas simplemente asumen que poner Business Logic en la base de datos siempre es incorrecto.

Se ha trabajado mucho para que el procesamiento de transacciones, especialmente las operaciones a granel, sea muy eficiente cuando se realiza en el lado de la base de datos. Además, la administración de códigos en las bases de datos ha mejorado enormemente ya que se formaron la mayoría de las opiniones contra las bases de datos.

Creo que es incorrecto considerar el servidor de la base de datos como solo una capa de persistencia. Si sus actividades de procesamiento son más eficientes cuando se realizan en el servidor de bases de datos, hágalo allí.

Si no, hágalo en otro lugar.

Todo se reduce a lo que mejor se adapta a la aplicación en la que está trabajando en este momento, el equipo con el que está trabajando y el cliente que lo contrató.

Eso solo mis 2 centavos.


La lógica de negocios debe ser encapsulada en un solo lugar. Podemos garantizar que la lógica siempre se ejecute y ejecute de manera coherente. Al usar las clases que deben ejecutarse todas las actividades que involucran a una entidad en la base de datos, podemos garantizar que toda la validación se ejecute correctamente. Hay un lugar para este código y cualquier desarrollador en el proyecto puede abrir fácilmente esta clase y ver la lógica (debido a que la documentación puede quedar desfasada y el código es la única forma confiable de documentación).

Esto es difícil de hacer con los procedimientos almacenados. Puede tener más de un sproc que trate con la (s) misma (s) tabla (s). Encadenar múltiples sprocs juntos para que la lógica resida en uno solo se vuelve difícil de manejar. Eso es un golpe. ¿Cómo se determina "¿Cuáles son todas las reglas de negocio que rodean a la entidad X" dentro de la base de datos? Diviértete buscando miles de sprocs tratando de rastrear eso.

El número dos es que estás atando tu lógica comercial a tu mecanismo de persistencia. No puede almacenar todos sus datos en la misma base de datos, o algunos pueden residir en XML, etc. Este tipo de inconsistencia es difícil para el desarrollador.

La validación es difícil de realizar si la lógica reside solo en la base de datos. ¿Realmente llamas a un sproc para validar cada campo en tu formulario de entrada de datos? Las reglas de validación y la lógica de negocios son primos cercanos. ¡Esta lógica debería realizarse en el mismo lugar!


Mis pocas observaciones:

A favor de los procedimientos almacenados:

  • después de algún tiempo de duración del proyecto, en la mayoría de los casos, el cuello de botella es la base de datos, no el servidor web, y los procedimientos almacenados son mucho, mucho más rápidos.

  • usar el generador de perfiles sql con las consultas SQL generadas por ORM es muy difícil; esto es fácil con procedimientos almacenados

  • puede implementar una solución para el procedimiento almacenado al instante, sin una ventana de servicio

  • para el rendimiento, es más fácil optimizar un procedimiento almacenado que el código ORM

  • Es posible que tenga muchas aplicaciones que usen los mismos db / procs almacenados

  • cualquier escenario de datos complejos es un voto para los procedimientos almacenados

A favor de la aplicación / ORM:

  • puedes usar repositorio de código (con procs almacenados aún es posible pero costoso)

  • El lenguaje java / c # es una mejor herramienta para expresar la lógica empresarial

  • java / c # es más fácil de depurar (a excepción del ORM generado de forma dinámica sql)

  • independencia del motor de base de datos (sin embargo, no es muy probable que un proyecto cambie la base de datos a otra)

  • ORM proporciona un modelo de datos que es fácil de usar

En mi opinión: para proyectos grandes, busque procedimientos almacenados, para los demás, la aplicación / ORM funcionará bien.

Al final de un día, lo único que importa es la base de datos.


Proyectos de alto presupuesto: si mantiene sus datos actualizados en la memoria y guarda los cambios en el disco periódicamente, querrá manejar la lógica de negocios aparte del servidor de db. Caso de uso: servir datos de ram, complejos mecanismos de caché.

Proyectos de bajo presupuesto: si mantiene los datos actualizados en el disco y su presentación depende de las lecturas del disco, manejar la lógica del negocio en los procedimientos almacenados puede ahorrarle tiempo de desarrollo. Caso de uso: servir datos del disco


Puede probar la lógica de negocio cuando está en una capa de lógica de negocios. Si está completamente separado, las operaciones de persistencia se pueden burlar, por lo que solo está probando el BL. Un proceso almacenado es mucho más difícil de mantener / depurar / prueba de unidad que, por ejemplo, linq y c #.


Soy de la escuela de pensamiento que dice eso siempre que la lógica de negocios:

  • vive en un lugar
  • donde está debidamente documentado
  • el acceso adecuado se proporciona a través de servicios que se pueden acoplar libremente
  • a través de una interfaz abstraída publicada

No me importa si la lógica vive en un procedimiento almacenado, en un nivel medio J2EE, en un sistema experto en clips, o donde sea. No importa dónde almacene nuestra lógica comercial, la "ley de conservación de la miseria" garantizará que alguien diga que fue una idea equivocada porque el componente / depósito X debe intercambiarse por tecnología / método Y.


Una razón más para NO almacenar lógica de negocios en sprocs - capacidades de escalado limitadas del DB. Es una situación muy común donde su base de datos es su cuello de botella, por eso es una buena idea tomar tanta carga del DB como sea posible.


Contra procedimientos almacenados: lógica de negocios en el espacio de programación

Le doy un gran valor al poder de expresión, y no creo que el espacio SQL sea tan expresivo. Use las mejores herramientas que tiene a mano para las tareas más adecuadas. Jugar con lógica y conceptos de orden superior se realiza mejor al más alto nivel. En consecuencia, el almacenamiento y la manipulación masiva de datos se realiza mejor a nivel de servidor, probablemente en procedimientos almacenados.

Pero depende. Si tiene múltiples aplicaciones que interactúan con un mecanismo de almacenamiento y desea asegurarse de que mantiene su integridad y flujo de trabajo, debe descargar toda la lógica en el servidor de la base de datos. O bien, prepárese para gestionar el desarrollo concurrente en múltiples aplicaciones.