Estoy trabajando en un proyecto en una de las 3 principales firmas de consultoría de TI del mundo, y un DBA me dijo que los procedimientos almacenados por el estado de las mejores prácticas de la compañía no son una "mejor práctica". Esto es muy contrario a todo lo que he aprendido.
Los procedimientos almacenados le brindan reutilización de código y encapsulación (dos pilares del desarrollo de software), seguridad (puede otorgar / revocar permisos en un proceso almacenado individual), protegerlo de ataques de inyección SQL y también ayudar con la velocidad (aunque ese DBA dijo que comenzando con SQL Server 2008 que incluso las consultas SQL regulares se compilan si se ejecutan suficientes veces).
Estamos desarrollando una aplicación compleja utilizando la metodología de desarrollo de software ágil. ¿Alguien puede pensar en buenas razones por las que no desearían usar procedimientos almacenados? Supuse que los DBA no querían mantener esos procesos almacenados, pero parece haber demasiados negativos para justificar tal decisión de diseño.
fuente
Respuestas:
En mi experiencia trabajando en proyectos muy grandes, debes tener muy claro dónde vive la lógica de negocios. Si permite un entorno donde los desarrolladores individuales pueden poner la lógica de negocios en la capa de objetos de negocio o en un procedimiento almacenado como mejor les parezca, una aplicación grande se vuelve MUY difícil de entender y mantener.
Los procedimientos almacenados son excelentes para acelerar ciertas operaciones de DB. Mi decisión arquitectónica es dejar toda la lógica en la capa empresarial de la aplicación y emplear procedimientos almacenados de manera específica para mejorar el rendimiento donde la evaluación comparativa indica que está justificado.
fuente
Algunas observaciones
Solo si los usa correctamente en el contexto en el que se supone que deben usarse. Se puede decir lo mismo sobre las funciones (en la programación estructurada) o los métodos (en la programación orientada a objetos) y, sin embargo, vemos funciones 1K y objetos mega-ass.
Los artefactos no te dan esos beneficios. El uso adecuado de esos artefactos es lo que da esos beneficios.
Si. Este es un buen punto y una de las razones principales por las que me gustan los procedimientos almacenados. Proporcionan un control de acceso de granularidad más fino que el que normalmente se puede lograr con solo vistas y cuentas de usuario.
Eso no es específico de los SP ya que puede lograr el mismo nivel de protección con sentencias SQL parametrizadas y depuración de entrada. Sin embargo, usaría SP además de esos, como cuestión de "seguridad en profundidad" .
Esto es altamente específico del proveedor de la base de datos, pero en general su DBA es correcto. Las declaraciones SQL (estáticas o parametrizadas) se compilan. Los SP ayudan si desea / necesita agregar y calcular datos que no puede hacer con declaraciones SQL simples, pero que están estrechamente integradas con SQL y no garantiza el viaje de ida y vuelta al servidor de aplicaciones.
Un buen ejemplo es consultar datos en un cursor (o cursores) temporal desde el cual ejecutar otro SQL. Puede hacerlo mediante programación en el servidor de aplicaciones, o puede guardar los múltiples viajes de ida y vuelta al hacerlo en la base de datos.
Sin embargo, esto no debería ser la norma. Si tiene muchos de esos casos, eso es una señal de un mal diseño de la base de datos (o está extrayendo datos de esquemas de bases de datos no tan compatibles entre departamentos).
La agilidad tiene que ver con los procesos de ingeniería de software y la gestión de requisitos, y no con las tecnologías.
Pregunta equivocada
La pregunta es incorrecta y equivale a preguntar "¿hay alguna buena razón para no usar GOTO"? Estoy más de acuerdo con Niklaus Wirth que con Dijkstra en este tema. Puedo entender de dónde vino el sentimiento de Dijkstra, pero no creo que sea 100% aplicable en todos los casos. Lo mismo con los accesorios de la tienda y cualquier tecnología.
Una herramienta es buena cuando se usa bien para su propósito previsto, y cuando es la mejor herramienta para la tarea en particular. Usarlo de otra manera no es una indicación de que la herramienta está mal, sino que el usuario no sabe lo que está haciendo.
La pregunta correcta es "qué tipo de patrones de uso de procedimientos almacenados se deben evitar". O "bajo qué condiciones debo (o no) usar procedimientos almacenados" . Buscar razones para no utilizar una tecnología es simplemente echarle la culpa a la herramienta en lugar de colocar la responsabilidad de ingeniería directamente donde pertenece: en el ingeniero.
En otras palabras, es una evasión o una declaración de ignorancia.
Lo que están haciendo es proyectar los resultados de sus malas decisiones de ingeniería sobre las herramientas que usaron mal.
¿Qué hacer en tu caso?
Mi experiencia es, cuando en Roma, hacer lo que hacen los romanos .
No luches contra eso. Si la gente de su empresa quiere etiquetar los procedimientos de la tienda como una mala práctica, déjelos. Sin embargo, tenga en cuenta que esto puede ser una señal de alerta en sus prácticas de ingeniería.
El etiquetado típico de las cosas como mala práctica generalmente se realiza en organizaciones con toneladas de programadores incompetentes. Al hacer una lista negra de ciertas cosas, la organización trata de limitar el daño infligido internamente por su propia incompetencia. No te cago.
Las generalizaciones son la madre de todos los errores. Decir que los procesos almacenados (o cualquier tipo de tecnología) son una mala práctica, es una generalización. Las generalizaciones son evasivas para los incompetentes. Los ingenieros no trabajan con generalizaciones descaradas. Realizan análisis caso por caso, analizan compensaciones y ejecutan decisiones y soluciones de ingeniería de acuerdo con los hechos en cuestión, en el contexto en el que se supone que deben resolver un problema.
Los buenos ingenieros no etiquetan las cosas como malas prácticas en formas tan generalizadas. Analizan el problema, seleccionan la herramienta adecuada y hacen compensaciones. En otras palabras, hacen ingeniería.
Mi opinión sobre cómo no usarlos
No ponga lógica compleja más allá de la recopilación de datos (y quizás algunas transformaciones) en ellos. Está bien poner alguna lógica de masaje de datos en ellos, o agregar el resultado de múltiples consultas con ellos. Pero eso es todo. Cualquier cosa más allá de eso calificaría como lógica de negocios que debería residir en otro lugar.
No los use como su único mecanismo de defensa contra la inyección SQL. Los deja allí en caso de que algo malo les llegue , pero debe haber una gran cantidad de lógica defensiva frente a ellos: validación / depuración del lado del cliente, validación / depuración del lado del servidor, posiblemente transformación en tipos que tengan sentido en su modelo de dominio, y finalmente pasar a declaraciones parametrizadas (que podrían ser declaraciones SQL parametrizadas o procesos almacenados parametrizados).
No hagas de las bases de datos el único lugar que contenga tus accesorios de la tienda. Los procs de tu tienda deben tratarse tal como tratas tu código fuente C # o Java. Es decir, la fuente controla la definición textual de los procs de tu tienda. La gente dice que los procs de la tienda no pueden ser controlados por la fuente: bullcrap, simplemente no saben de qué demonios están hablando.
Mi opinión sobre cómo / dónde usarlos
Su aplicación requiere datos que deben transponerse o agregarse desde múltiples consultas o vistas. Puede descargar eso desde la aplicación a la base de datos. Aquí debe hacer un análisis de rendimiento ya que a) los motores de bases de datos son más eficientes que los servidores de aplicaciones para hacer estas cosas, pero b) los servidores de aplicaciones son (a veces) más fáciles de escalar horizontalmente.
Control de acceso de grano fino. No desea que algún idiota ejecute uniones cartesianas en su base de datos, pero tampoco puede prohibir a las personas que ejecuten sentencias SQL arbitrarias así. Una solución típica es permitir sentencias SQL arbitrarias en entornos de desarrollo y UAT, al tiempo que las prohíbe en entornos sistemáticos y de producción. Cualquier declaración que deba llegar al sistema o producción entra en un procedimiento de tienda, revisado por código tanto por desarrolladores como por dbas.
Cualquier necesidad válida de ejecutar una instrucción SQL que no esté en un proceso de tienda pasa por un nombre de usuario / cuenta diferente y un grupo de conexiones (con el uso altamente monitoreado y desaconsejado).
Si ejecuta esto en la base de datos como un proceso de tienda o en su servidor de aplicaciones depende del análisis de compensación que usted, como ingeniero, debe hacer. Ambas opciones deben analizarse y justificarse con algún tipo de análisis. Ir de una forma u otra simplemente acusando a la otra alternativa como "mala práctica", eso es solo una cojera ingenua.
Si eso se convierte en una solución permanente o no, eso es específico de las restricciones observadas en ese momento en particular.
Espero eso ayude.
fuente
La razón es que confiar en una capa de procedimiento almacenado limita la portabilidad y lo vincula a un determinado DB. Los costos de mantenimiento adicionales también se citan como una razón. También quería comentar sobre este punto que hizo:
En realidad, son las consultas parametrizadas las que lo protegen, lo que puede hacer fácilmente en consultas SQL sin formato.
fuente
+ "blablabla"
porque debe permitir SQL simple, y ahí es donde termina el control.Algunas de las razones por las que estoy de acuerdo con los procedimientos almacenados no son una buena práctica.
fuente
Sí, pero a costa de poder alcanzar otros objetivos de diseño ágiles. Son más difíciles de mantener, por un lado. Si el proyecto en el que estoy es una indicación, es probable que termines con múltiples SP incompatibles que hacen esencialmente el mismo trabajo, sin ningún beneficio.
No ellos no. Ni siquiera puedo comenzar a adivinar de dónde podría haber surgido esta idea, como lo escucho decir a menudo, y simplemente no es cierto. Puede mitigar ciertos tipos de ataques de inyección SQL, pero si no está utilizando consultas parametrizadas en primer lugar, eso no importará. Todavía puedo '; DROP TABLE Cuentas -
También suelen compilarse cuando usa declaraciones preparadas y parametrizadas (al menos con varias de las bases de datos que he usado). Cuando su aplicación comienza a ejecutar la consulta (o especialmente cuando ejecuta la misma consulta preparada varias veces), cualquier ventaja de rendimiento que cree que tiene su SP es completamente discutible.
La única razón para usar un procedimiento almacenado, en mi humilde opinión, es cuando debe hacer una consulta compleja y de varias etapas que extrae de múltiples fuentes clasificadas. Los SP no deberían contener una lógica de decisión de bajo nivel, y nunca deberían simplemente encapsular una consulta simple. No hay beneficios y solo muchos inconvenientes.
Escucha a tu DBA. Él sabe lo que pasa.
fuente
Esta fue la línea oficial cuando trabajé para uno de los Big Five hace unos años. La razón era que, dado que los SP están vinculados a implementaciones particulares (PL / SQL vs T / SQL vs ...), limitan innecesariamente las opciones tecnológicas.
Habiendo vivido la migración de un sistema grande de T / SQL a PL / SQL, puedo entender el argumento. Sin embargo, creo que es un poco tonto: ¿cuántos lugares realmente se mueven de una base de datos a otra por capricho?
fuente
Las tres empresas para las que trabajo utilizan procedimientos almacenados para su lógica de aplicación con SQL Server. Realmente no he visto las cosas al revés. Pero para mí son un gran desastre. Por lo general, no hay muy buenas instalaciones de manejo de errores o instalaciones de reutilización de código con procedimientos almacenados.
Digamos que tiene un procedimiento almacenado que devuelve un conjunto de datos que desea usar, ¿cómo puede usarlo en futuros procedimientos almacenados? Los mecanismos en SQL Server para eso no son muy buenos. EJECUTAR EN ... solo funciona en uno o dos niveles) de anidamiento (lo olvido ahora). O tiene que predefinir una tabla de trabajo y hacer que procese la clave. O necesita crear previamente una tabla temporal y hacer que el procedimiento la complete. Pero, ¿qué pasa si dos personas llaman a una tabla temporal lo mismo en dos procedimientos diferentes que nunca planearon usar al mismo tiempo? En cualquier lenguaje de programación normal, puede devolver una matriz de una función o señalar a un objeto / estructura global compartida entre ellos (excepto los lenguajes funcionales donde devolvería la estructura de datos en lugar de simplemente cambiar una estructura global ... )
¿Qué tal la reutilización del código? Si comienza a poner expresiones comunes en UDF (o incluso peores subconsultas), ralentizará el código. No puede llamar a un procedimiento almacenado para realizar un cálculo para una columna (a menos que use un cursor, pase los valores de la columna uno por uno y luego actualice su tabla / conjunto de datos de alguna manera). Básicamente, para obtener el máximo rendimiento, debe cortar / pegar expresiones comunes en todo el lugar, lo cual es una pesadilla de mantenimiento ... Con un lenguaje de programación, puede crear una función para generar el SQL común y luego llamarlo desde cualquier lugar al construir La cadena SQL. Luego, si necesita ajustar la fórmula, puede hacer el cambio en un solo lugar ...
¿Qué tal el manejo de errores? SQL Server tiene muchos errores que inmediatamente detienen la ejecución del procedimiento almacenado y algunos incluso fuerzan una desconexión. Desde 2005 hay try / catch pero todavía hay una serie de errores que no se pueden detectar. También ocurre lo mismo con la duplicación de código en el código de manejo de errores y realmente no puede pasar las excepciones tan fácilmente o subirlas a niveles más altos tan fácilmente como la mayoría de los lenguajes de programación .....
También solo velocidad. Muchas operaciones en conjuntos de datos no están orientadas a SET. Si intentas hacer cosas orientadas a filas, o vas a usar un cursor, o vas a usar un "cursor" (cuando los desarrolladores a menudo consultan cada fila una por una y almacenan el contenido en variables @ como un cursor. .. Aunque esto es a menudo más lento que un cursor FORWARD_ONLY). Con SQL Server 2000 tuve algo que se ejecutó durante 1 hora antes de matarlo. Reescribí ese código en Perl y terminó en 20 minutos. Cuando un lenguaje de secuencias de comandos que es 20-80x más lento que C fuma SQL en rendimiento, definitivamente no tiene por qué escribir operaciones orientadas a filas en SQL.
Ahora SQL Server tiene integración CLR y muchos de estos problemas desaparecen si usa procedimientos almacenados CLR. Pero muchos DBA no saben cómo escribir programas .NET o apagar el CLR debido a problemas de seguridad y seguir con Transact SQL ... Además, incluso con los CLR, todavía tiene problemas para compartir datos entre múltiples procedimientos de manera eficiente .
También, en general, lo más difícil de escalar es la base de datos. Si toda su lógica empresarial está en la base de datos, cuando la base de datos se vuelva demasiado lenta, tendrá problemas. Si tiene una capa empresarial, puede agregar más almacenamiento en caché y más servidores empresariales para aumentar el rendimiento. Tradicionalmente, otro servidor para instalar Windows / Linux y ejecutar .NET / Java es mucho más barato que comprar otro servidor de base de datos y licenciar más SQL Server. Sin embargo, SQL Server ahora tiene más soporte de agrupación, originalmente no tenía ninguno. Entonces, si tiene mucho dinero, puede agregar clústeres o incluso hacer algunos envíos de registros para hacer múltiples copias de solo lectura. Pero en general, esto costará mucho más que solo tener una escritura detrás de la caché o algo así.
También mire las instalaciones de Transact-SQL. Manipulación de cuerdas? Tomaré las clases Java String Class / Tokenizer / Scanner / Regex cualquier día. Tablas hash / Listas vinculadas / Etc. Tomaré los marcos de Java Collection, etc ... Y lo mismo para .NET ... Tanto C # como Java son lenguajes mucho más evolucionados que Transact SQL ... La codificación de Heck con Transact-SQL me pone celoso de C ... .
Además, los procedimientos almacenados son más eficientes para trabajar con un gran conjunto de datos y aplicar múltiples consultas / criterios para reducirlo antes de devolverlo a la capa empresarial. Si tiene que enviar un conjunto de grandes conjuntos de datos a la aplicación del cliente y desglosar los datos en el cliente, será mucho más ineficiente que simplemente hacer todo el trabajo en el servidor.
También los procedimientos almacenados son buenos para la seguridad. Puede cortar todo el acceso a las tablas subyacentes y solo permitir el acceso a través de los procedimientos almacenados. Con algunas técnicas modernas como XML, puede tener procedimientos almacenados que realizan actualizaciones por lotes. Luego, todo el acceso se controla a través de los procedimientos almacenados, de modo que siempre que sean seguros / correctos, los datos pueden tener más integridad.
El argumento de inyección SQL ya no se aplica tanto, ya que tenemos consultas parametrizadas en el lado del lenguaje de programación. También, incluso antes de las consultas parametrizadas, un poco de reemplazo ("'", "' '") funcionó la mayor parte del tiempo también (aunque todavía hay trucos para usar para pasar el final de la cadena para obtener lo que desea).
En general, creo que SQL y Transact SQL son excelentes lenguajes para consultar / actualizar datos. Pero para codificar cualquier tipo de lógica, manipular cadenas (o manipular archivos ... te sorprendería lo que puedes hacer con xp_cmdshell ...), por favor no. Espero encontrar un lugar futuro que no utilice principalmente procedimientos almacenados. Desde el punto de vista del mantenimiento del código, son una pesadilla. Además, qué sucede si desea cambiar de plataforma (aunque realmente si pagó por Oracle / DB2 / Sybase / Sql Server / etc., también podría obtener todo lo que pueda de ellos utilizando todas las extensiones propietarias que pueda que lo ayuden. ..).
También sorprendentemente a menudo la lógica de negocios no es la misma. En el mundo ideal, pondría toda la lógica en los procedimientos almacenados y la compartiría entre aplicaciones. Pero a menudo la lógica difiere según las aplicaciones y sus procedimientos almacenados terminan convirtiéndose en monolitos demasiado complejos que las personas tienen miedo de cambiar y no comprenden todas las implicaciones. Mientras que con un buen lenguaje orientado a objetos puede codificar una capa de acceso a datos que tiene algunas interfaces / ganchos estándar que cada aplicación puede anular según sus propias necesidades.
fuente
¿Cómo versionan los procedimientos almacenados en el servidor?
Si vuelve a implementar procedimientos almacenados en el servidor desde el control de versiones, elimina el plan de ejecución almacenado.
Los procedimientos almacenados no deben modificarse directamente en el servidor, de lo contrario, ¿cómo sabe qué está funcionando realmente _ ahora mismo? Si no lo están, la herramienta de implementación necesita acceso para escribir procedimientos almacenados en la base de datos. Tendría que implementar en cada compilación (el plan ejecutivo podría ser diferente)
Si bien los procedimientos almacenados no son portables, tampoco lo es SQL en general (manejo de fecha de oráculo visto alguna vez - uggghhh).
Entonces, si desea portabilidad, cree una API interna de acceso a datos. Puede llamar a esto como llamadas de función, e internamente puede incorporar la jerga que desee, con consultas parametrizadas, y puede controlarse según la versión.
fuente
Es posible que necesite salir más. [sonríe] En serio, los procesos almacenados han estado en declive durante al menos 10 años. Casi desde que n-tier reemplazó cliente-servidor. La disminución solo se aceleró con la adopción de lenguajes OO como Java, C #, Python, etc.
Eso no quiere decir que los procedimientos almacenados aún no tengan sus defensores y defensores, pero esta es una discusión y debate de larga duración. No es nuevo, y probablemente continuará durante bastante tiempo; En mi opinión, los oponentes de los procesos almacenados están claramente ganando.
Muy cierto. Pero, también lo hace una capa OO de arquitectura decente.
Si bien puede hacerlo, pocos lo hacen debido a las graves limitaciones. La seguridad en el nivel de base de datos no es lo suficientemente granular como para tomar decisiones sensibles al contexto. Debido a la sobrecarga de rendimiento y administración, es inusual tener conexiones por usuario también, por lo que aún necesita cierto nivel de autorización en el código de su aplicación. Puede usar inicios de sesión basados en roles, pero necesitará crearlos para nuevos roles, mantener el rol que está ejecutando, cambiar las conexiones para hacer un trabajo de "nivel de sistema" como el registro, etc. Y, al final, si su aplicación es propiedad, también lo es su conexión a la base de datos.
No más que hacer consultas parametrizadas. Que se necesita para hacer de todos modos.
Creo que eso comenzó en MSSQL 7 o 2000. Ha habido muchos debates, mediciones y desinformación sobre el proceso almacenado vs el rendimiento de SQL en línea: lo agrupo todo bajo YAGNI. Y, si lo necesita, pruebe.
No puedo pensar en muchas razones por las que querrías hacerlo. Java / C # / cualquier lenguaje 3rd GL son mucho más capaces que T-SQL en encapsulación, reutilización y felxibilidad, etc. La mayoría de los cuales es gratis dado un ORM medio decente.
Además, dado el consejo de "distribuir según sea necesario, pero no más", creo que la carga de la prueba en estos días recae en los defensores de SP. Una razón común para que el proceso almacenado sea pesado es que T-SQL es más fácil que OO, y la tienda tiene mejores desarrolladores de T-SQL que OO. O bien, que el DBA se detiene en la capa de la base de datos y que los procesos almacenados son la interfaz entre dev y DBA. O bien, está enviando un producto semi-personalizado y los procesos almacenados pueden ser personalizados por el usuario. En ausencia de algunas consideraciones como esa, creo que el valor predeterminado para cualquier proyecto Agile SW en estos días será ORM.
fuente
Teniendo en cuenta todos los casos anteriores, me gustaría agregar uno más. La elección de SP puede depender también de la elección de las personas.
Personalmente, me siento frustrado cuando la gente pone una lógica muy compleja en SP y creo que dicho SP es muy complejo de mantener y depurar. Incluso en muchos casos, el propio desarrollador enfrenta problemas cuando la depuración del código subyacente (por ejemplo, parte del lenguaje) es mucho más fácil que en SP.
SP solo debe usarse para operaciones simples. Bueno, esa es mi elección.
fuente
Quiero cubrir algunos problemas a favor y en contra con los procs almacenados. Los usamos ampliamente con LedgerSMB , y nuestra regla es, con algunas extensiones muy específicas, "si se trata de una consulta, conviértala en un proceso almacenado".
Nuestra razón para hacerlo fue facilitar la reutilización de consultas en varios idiomas. No hay una mejor manera de hacerlo honestamente.
Al final, la pregunta siempre está en los detalles. Los procedimientos bien utilizados y almacenados hacen las cosas mucho más fáciles, y mal utilizados hacen las cosas mucho más difíciles.
Así que por el lado de la estafa.
Como se usa tradicionalmente, los procedimientos almacenados son frágiles. Utilizados solos, crean la posibilidad de agregar errores a su código en lugares que no esperaba por ninguna otra razón que la sintaxis de la llamada cambió. Usado solo, esto es un pequeño problema. Hay demasiada cohesión entre las capas y esto causa problemas.
Sí, es posible tener una inyección sql intra-sproc si se hace un sql dinámico. Es malo confiar demasiado en esta área y, en consecuencia, uno debe tener una experiencia significativa en seguridad en esta área.
Los cambios en las interfaces son algo problemáticos con los procedimientos almacenados por la razón # 1 anterior, pero esto puede convertirse en una gran pesadilla si hay un gran número de aplicaciones cliente involucradas.
Lo anterior es bastante difícil de negar. Ellos pasan. Todos, pro-SP y anti-SP probablemente han tenido historias de terror con respecto a estos. Los problemas no son irresolubles, pero si no les presta atención, no puede resolverlos (en LedgerSMB usamos un localizador de servicios para generar dinámicamente llamadas SP en tiempo de ejecución, evitando los problemas anteriores por completo. Si bien somos PostgreSQL solo, algo similar podría hacerse para otros db's).
En lo positivo. Suponiendo que puede resolver los problemas anteriores, obtiene:
La posibilidad de mayor claridad en las operaciones de configuración. Esto es particularmente cierto si su consulta es muy grande o muy flexible. Esto también conduce a una capacidad de prueba mejorada.
Si ya tengo un localizador de servicios trabajando en esta área, encuentro que los procedimientos almacenados aceleran el ritmo de desarrollo porque liberan al desarrollador de la aplicación de las preocupaciones de db y viceversa. Esto tiene algunas dificultades para hacer lo correcto, pero no es tan difícil de hacer.
Consulta de reutilización.
Ah, y algunas cosas que casi nunca debes hacer en un SP:
lógica no transaccional. Envió el correo electrónico indicando que se envió el pedido pero la transacción se retiró ... o ahora está esperando continuar para que el servidor de correo electrónico se conecte ... o, peor aún, revierta su transacción solo porque no puede comunicarse con el servidor de correo electrónico ...
muchas pequeñas consultas unidas libremente, salpicadas de lógica de procedimiento ...
fuente
¿Para quién trabajas?
La respuesta puede depender de con quién está empleado, la empresa de consultoría o la propia empresa. Lo que es mejor para una empresa a menudo no es lo mejor para una empresa consultora u otro proveedor de software. por ejemplo, una empresa inteligente desea tener una ventaja permanente sobre sus competidores Por el contrario, un proveedor de software quiere poder ofrecer la misma solución a todas las empresas en una industria en particular, por el costo más bajo. Si tienen éxito en esto, no habrá una ventaja competitiva neta para el cliente.
En este caso particular, las aplicaciones van y vienen, pero muy a menudo, la base de datos corporativa vive para siempre. Una de las cosas principales que hace un RDBMS es evitar que los datos basura ingresen a la base de datos. Esto puede involucrar procedimientos almacenados. Si la lógica es buena lógica y es muy poco probable que cambie de año en año, ¿por qué no debería estar en la base de datos, manteniéndola internamente consistente, independientemente de la aplicación que se escriba para usar la base de datos? Años más tarde, alguien tendrá una pregunta que quiera hacerle a la base de datos y responderá si se ha impedido que la basura ingrese a la base de datos.
Entonces, tal vez esto tenga algo que ver con el hecho de que su DBA trabaja para una empresa de consultoría. Cuanto más portátiles puedan hacer su código, más podrán reutilizar el código de cliente a cliente. Cuanto más lógica puedan vincular en su aplicación, más se unirá la empresa al proveedor. Si dejan un gran desorden en el proceso, se les pagará por limpiarlo o nunca volverán a ver el desorden. De cualquier manera, es una victoria para ellos.
Para (mucha) más discusión en ambos lados de la cerca, lea la discusión sobre codificación del horror . FWIW Me inclino al lado de aquellos que abogan por los SP.
fuente
Es muy difícil cambiar las marcas de la base de datos y utilizar los mismos procedimientos almacenados.
Su equipo tampoco tiene un DBA y nadie más quiere tener nada que ver con sql.
Esto no es más que un concurso de meado programador v DBA.
fuente
OMI depende. Los procedimientos almacenados tienen su lugar, pero no son una mejor práctica, ni tampoco deben evitarse a toda costa. Un desarrollador inteligente sabe cómo evaluar adecuadamente una situación dada y determinar si un procedimiento almacenado es la respuesta. Personalmente, soy fanático de usar un ORM de algún tipo (incluso uno básico como Linq a SQL sin procesar) en lugar de procedimientos almacenados, excepto tal vez para informes predefinidos o similares, pero de nuevo es realmente una base de caso por caso.
fuente
Siempre es una fuente de problemas tener la lógica de negocios dividida entre diferentes capas, usando diferentes lenguajes de programación. Rastrear un error o implementar un cambio es mucho más difícil cuando tienes que cambiar entre mundos.
Dicho esto, conozco compañías que funcionan bastante bien al poner toda la lógica de negocios en paquetes PL / SQL que viven en la base de datos. Esas no son aplicaciones muy grandes, pero tampoco triviales; decir 20K-100K LOC. (PL / SQL es más adecuado para ese tipo de sistema que T-SQL, por lo que si solo conoce T-SQL, probablemente sacuda la cabeza con incredulidad ahora ...)
fuente
Este es otro punto aún no mencionado:
Las herramientas de generación de código y las herramientas de ingeniería inversa realmente no pueden hacer frente a los procedimientos almacenados. La herramienta generalmente no puede decir qué hace el proceso. ¿El proceso devuelve un conjunto de resultados? Varios conjuntos de resultados? ¿Obtiene sus conjuntos de resultados de varias tablas y tablas temporales? ¿Es el proceso solo una declaración de actualización encapsulada y no devuelve nada? ¿Devuelve un conjunto de resultados, un valor de retorno y alguna "salida de consola"?
Por lo tanto, si desea utilizar una herramienta para crear una capa DTO y DAO de objetos de transferencia de datos automáticamente (como lo hace el "creador de servicios" de liferay), no puede hacerlo fácilmente.
Además, los ORM como Hibernate realmente no pueden funcionar correctamente cuando la fuente de datos es un SP. El acceso a datos es de solo lectura en el mejor de los casos.
fuente
Programando solo, no puedo resistirme a escribir procedimientos almacenados.
Estoy usando MySQL principalmente. No he usado bases de datos orientadas a objetos antes como PostGreSQL, pero lo que puedo hacer con los SP en MySQL es abstraer un poco la estructura de la tabla. SP a permitir que diseñe estas acciones primitivas, cuyas entradas y salidas no va a cambiar , incluso si la base de datos por debajo de ella no cambia.
Entonces, tengo un procedimiento llamado
logIn
. Cuando inicia sesión, siempre pasausername
ypassword
. El resultado devuelto es el enterouserId
.Cuando se
logIn
trata de un procedimiento almacenado, ahora puedo agregar trabajo adicional para realizar al iniciar sesión que ocurre al mismo tiempo que el inicio de sesión inicial. Encuentro una serie de instrucciones SQL con lógica incorporada en un procedimiento almacenado más fácil de escribir que ( Entorno FETCH) -> (obtener resultado) -> (llamando al entorno FETCH) serie que tienes que hacer cuando escribes el lado del servidor lógico.fuente
También quiero señalar que los procedimientos almacenados usan tiempo de CPU en el servidor. No mucho, pero algo. Parte del trabajo realizado en el procedimiento de trabajo podría realizarse en la aplicación. Es más fácil escalar la capa de la aplicación que la capa de datos.
fuente
Estoy de acuerdo con Mark en que la comunidad realmente se ha alejado de los procedimientos almacenados durante bastante tiempo. Si bien muchos de los puntos que el póster original planteó por qué podríamos querer usar SP fueron válidos en algún momento, ha pasado bastante tiempo y, como dijo otro póster, el entorno ha cambiado. Por ejemplo, recuerdo que un argumento PARA usar los SP 'en el día' fue el aumento de rendimiento logrado porque sus planes de ejecución fueron 'precompilados' mientras que el SQL dinámico de nuestro código tuvo que 'volver a compilarse' con cada ejecución. Este ya no es el caso, ya que las principales bases de datos han cambiado, mejorado, adaptado, etc.
Dicho esto, estamos usando SP en mi proyecto actual. La razón es simplemente porque estamos creando nuevas aplicaciones sobre una base de datos existente que aún admite aplicaciones heredadas. Como resultado, hacer cambios de esquema es muy difícil hasta que apaguemos las aplicaciones heredadas. Tomamos una decisión consciente de diseñar nuestras nuevas aplicaciones basadas en el comportamiento y las reglas requeridas para la aplicación y usar los SP para interactuar temporalmente con la base de datos de la manera que nos gustaría que fuera y permitir que los SP se adapten al SQL existente . Esto va al punto de un póster anterior de que los SP facilitan hacer cambios a nivel de la base de datos sin requerir cambios en el código de la aplicación. Usar SP como una implementación del patrón Adaptador ciertamente tiene sentido para mí (especialmente dado mi proyecto actual),
Fwiw, nuestra intención es eliminar los SP cuando se actualiza el esquema. Pero, como con todo lo demás en el desarrollo corporativo, ¡veremos si eso sucede alguna vez! [mueca]
fuente
Solo quería hacer una descripción concisa de cómo recomendaría usar procedimientos almacenados. No creo que sean una mala práctica en absoluto, y como otros han dicho, deberían usarse en las situaciones adecuadas.
Puedo ver problemas en los que escribir procedimientos para diferentes aplicaciones puede volverse confuso en funcionalidad y separar la lógica de negocios de la aplicación y hacer que la base de datos se vuelva más desorganizada y restrictiva también.
Por lo tanto, usaría un procedimiento almacenado en tareas orientadas a datos relacionales específicas de la base de datos. En otras palabras, si hay una lógica utilizada para las operaciones de la base de datos que es consistente con los datos de cualquier aplicación, se podría usar un procedimiento almacenado para mantener los datos almacenados de manera consistente (tiene sentido). Creo que buenos ejemplos de esto son: registro consistente, mantenimiento consistente, trabajar con información confidencial, etc.
Creo que otras tareas que manipulan los datos para ajustarse a las necesidades de la aplicación que siguen el sólido modelo de datos de la base de datos deberían almacenarse en otra capa que contenga la lógica empresarial. En resumen, la manipulación de datos específicos de la base de datos para la coherencia podría usar procedimientos almacenados, donde la coherencia se extiende más allá del modelo de esquema de integridad de la base de datos.
fuente
Los procedimientos almacenados "para mí" son adecuados para operaciones OLAP de "solo lectura", de uso poco frecuente.
Para las reglas comerciales, las operaciones de lectura / escritura OLTP prefiero los servidores de aplicaciones Java. Para facilitar la codificación y, en la medida de lo posible, aliviar la carga de CPU y memoria de los servidores db maestros. En esta configuración, todo el código en los servidores de aplicaciones no es difícil de revisar o registrar y es escalable.
Lo importante para mí es que es más fácil depurar en la capa empresarial que depurar procedimientos almacenados.
fuente
Además de distribuir la lógica de negocios innecesariamente y de vincularlo con un proveedor de base de datos específico, también creo firmemente en el uso de una tecnología para lo que estaba destinado. Una base de datos es solo eso, un almacén de datos relacionales. Úselo para almacenar datos, nada más.
Elija sus herramientas sabiamente y se ahorrará un mundo de dolor a largo plazo.
fuente