¿Cuáles son las ventajas / desventajas de mantener SQL en su código fuente de C # o en Procs almacenados? He estado discutiendo esto con un amigo en un proyecto de código abierto en el que estamos trabajando (C # ASP.NET Forum). Por el momento, la mayor parte del acceso a la base de datos se realiza construyendo el SQL en línea en C # y llamando a la base de datos de SQL Server. Así que estoy tratando de establecer cuál, para este proyecto en particular, sería mejor.
Hasta ahora tengo:
Ventajas para en Código:
- Más fácil de mantener: no es necesario ejecutar un script SQL para actualizar las consultas
- Más fácil de portar a otra base de datos: no hay procesos a puerto
Ventajas para los Procs almacenados:
- Actuación
- Seguridad
Respuestas:
No soy fanático de los procedimientos almacenados
Terminará recompilándolo de todos modos cuando los tipos de datos cambien, o desee devolver una columna adicional, o lo que sea. El número de veces que puede cambiar 'transparentemente' el SQL desde debajo de su aplicación es bastante pequeño en general
Los lenguajes de programación, C # incluido, tienen esta increíble cosa, llamada función. ¡Significa que puede invocar el mismo bloque de código desde múltiples lugares! ¡Asombroso! Luego puede poner el código SQL reutilizable dentro de uno de estos, o si desea obtener tecnología realmente alta, puede usar una biblioteca que lo haga por usted. Creo que se llaman asignadores relacionales de objetos, y son bastante comunes en estos días.
De acuerdo, por eso los programas almacenados son algo malo. Es mucho más fácil refactorizar y descomponer (dividir en partes más pequeñas) el código en funciones que SQL en ... ¿bloques de SQL?
¿Por qué sus aplicaciones de Windows se conectan directamente a una base de datos central? Eso parece un enorme agujero de seguridad allí mismo, y un cuello de botella, ya que descarta el almacenamiento en caché del lado del servidor. ¿No deberían conectarse a través de un servicio web o similar a sus servidores web?
Entonces, ¿empuja 1 nuevo sproc o 4 nuevos servidores web?
En este caso, es más fácil empujar una nueva sproc, pero en mi experiencia, el 95% de los 'cambios empujados' afectan el código y no la base de datos. Si está enviando 20 cosas a los servidores web ese mes, y 1 a la base de datos, difícilmente perderá mucho si en cambio empuja 21 cosas a los servidores web y cero a la base de datos.
¿Puedes explicar cómo? No entiendo esto. Particularmente, ya que los sprocs probablemente no están en el control de fuente y, por lo tanto, no se puede acceder a ellos a través de navegadores SCM basados en web, etc.
Más contras:
Los Storedprocs viven en la base de datos, que aparece en el mundo exterior como una caja negra. Cosas simples como querer ponerlos en control de la fuente se convierten en una pesadilla.
También está la cuestión del puro esfuerzo. Puede tener sentido dividir todo en un millón de niveles si está tratando de justificar a su CEO por qué solo les costó 7 millones de dólares construir algunos foros, pero de lo contrario, crear un procedimiento almacenado para cada pequeña cosa es simplemente un trabajo de burro adicional para nada beneficio.
fuente
Esto se está discutiendo en algunos otros hilos aquí actualmente. Soy un defensor constante de los procedimientos almacenados, aunque se presentan algunos buenos argumentos para Linq to Sql.
Incrustar consultas en su código lo vincula estrechamente a su modelo de datos. Los procedimientos almacenados son una buena forma de programación contractual, lo que significa que un DBA tiene la libertad de alterar el modelo de datos y el código en el procedimiento, siempre que se mantenga el contrato representado por las entradas y salidas del procedimiento almacenado.
Ajustar las bases de datos de producción puede ser extremadamente difícil cuando las consultas están ocultas en el código y no en una ubicación central y fácil de administrar.
[Editar] Aquí hay otra discusión actual
fuente
En mi opinión, no puedes votar sí o no en esta pregunta. Depende totalmente del diseño de su aplicación.
Voto totalmente en contra del uso de SP en un entorno de 3 niveles, donde tienes un servidor de aplicaciones al frente. En este tipo de entorno, su servidor de aplicaciones está allí para ejecutar su lógica empresarial. Si además usa SP, comienza a distribuir su implementación de lógica de negocios en todo su sistema y no quedará muy claro quién es responsable de qué. Eventualmente terminará con un servidor de aplicaciones que básicamente no hará nada más que lo siguiente:
Entonces, al final, tienes tu nivel medio ejecutándose en este genial clúster de 4 servidores, cada uno de ellos equipado con 16 CPU y ¡en realidad no hará nada en absoluto! ¡Que desperdicio!
Si tiene un cliente de interfaz gráfica de usuario que se conecta directamente a su base de datos o tal vez incluso más aplicaciones, es una historia diferente. En esta situación, los SP pueden servir como una especie de pseudo nivel intermedio que desacopla su aplicación del modelo de datos y ofrece un acceso controlable.
fuente
En realidad, creo que tienes eso al revés. En mi humilde opinión, SQL en el código es difícil de mantener porque:
Piense en los procedimientos almacenados como métodos a los que llama desde el objeto de la base de datos: son mucho más fáciles de reutilizar, solo hay un lugar para editar y, en caso de que cambie los proveedores de bases de datos, los cambios ocurren en sus procedimientos almacenados y no en su código .
Dicho esto, las ganancias de rendimiento de los procesos almacenados son mínimas como Stu dijo antes que yo y no se puede poner un punto de interrupción en un procedimiento almacenado (todavía).
fuente
ESTAFA
Me parece que hacer mucho procesamiento dentro de los procedimientos almacenados haría que su servidor de DB sea un punto único de inflexibilidad, cuando se trata de escalar su acto.
Sin embargo, hacer todo ese trabajo en su programa en lugar del servidor SQL, podría permitirle escalar más si tiene varios servidores que ejecutan su código. Por supuesto, esto no se aplica a los procesos almacenados que solo realizan la recuperación o actualización normal, sino a los que realizan más procesamiento como bucle sobre conjuntos de datos.
PROS
fuente
La ventaja de rendimiento para los procedimientos almacenados es a menudo insignificante.
Más ventajas para los procedimientos almacenados:
fuente
Me caigo del lado del código . Creamos una capa de acceso a datos que utilizan todas las aplicaciones (tanto web como cliente), por lo que es SECO desde esa perspectiva. Simplifica la implementación de la base de datos porque solo tenemos que asegurarnos de que los esquemas de la tabla sean correctos. Simplifica el mantenimiento del código porque no tenemos que mirar el código fuente y la base de datos.
No tengo muchos problemas con el acoplamiento estrecho con el modelo de datos porque no veo dónde es posible realmente romper ese acoplamiento. Una aplicación y sus datos están inherentemente acoplados.
fuente
Procedimientos almacenados.
Si un error se desliza o la lógica cambia un poco, no tiene que volver a compilar el proyecto. Además, permite el acceso desde diferentes fuentes, no solo desde el lugar donde codificó la consulta en su proyecto.
No creo que sea más difícil mantener los procedimientos almacenados, no debe codificarlos directamente en la base de datos, sino primero en archivos separados, luego puede ejecutarlos en cualquier base de datos que necesite configurar.
fuente
Ventajas para procedimientos almacenados :
Código revisado más fácilmente.
Menos acoplado, por lo tanto, más fácilmente probado.
Más fácilmente sintonizado.
El rendimiento generalmente es mejor, desde el punto de vista del tráfico de red: si tiene un cursor o similar, entonces no hay múltiples viajes a la base de datos
Puede proteger el acceso a los datos con mayor facilidad, eliminar el acceso directo a las tablas, hacer cumplir la seguridad a través de los procesos; esto también le permite encontrar relativamente rápido cualquier código que actualice una tabla.
Si hay otros servicios involucrados (como los servicios de informes), puede que le resulte más fácil almacenar toda su lógica en un procedimiento almacenado, en lugar de en código, y tener que duplicarlo
Desventajas
Más difícil de administrar para los desarrolladores: control de versiones de los scripts: ¿todos tienen su propia base de datos, está integrado el sistema de control de versiones con la base de datos y el IDE?
fuente
En algunas circunstancias, el código SQL creado dinámicamente puede tener un mejor rendimiento que un proceso almacenado. Si ha creado un proceso almacenado (digamos sp_customersearch) que se vuelve extremadamente complicado con docenas de parámetros porque debe ser muy flexible, probablemente pueda generar una instrucción sql mucho más simple en el código en tiempo de ejecución.
Se podría argumentar que esto simplemente mueve parte del procesamiento de SQL al servidor web, pero en general eso sería algo bueno.
La otra gran cosa acerca de esta técnica es que si está buscando en el generador de perfiles SQL, puede ver la consulta que generó y depurarla mucho más fácilmente que ver una llamada de proceso almacenada con 20 parámetros.
fuente
Me gustan los procesos almacenados, no sé cuántas veces pude hacer un cambio en una aplicación utilizando un procedimiento almacenado que no produjo ningún tiempo de inactividad en la aplicación.
Gran fanático de Transact SQL, ajustar grandes consultas ha demostrado ser muy útil para mí. ¡No escribí ningún SQL en línea en aproximadamente 6 años!
fuente
Usted enumera 2 puntos pro para los sprocs:
Rendimiento, no realmente. En SQL 2000 o superior, las optimizaciones del plan de consulta son bastante buenas y se almacenan en caché. Estoy seguro de que Oracle, etc., hace cosas similares. Ya no creo que haya un caso para los sprocs para el rendimiento.
¿Seguridad? ¿Por qué los sprocs serían más seguros? A menos que tenga una base de datos bastante insegura, todo el acceso será desde sus DBA o mediante su aplicación. Parametrice siempre todas las consultas: nunca inserte algo de la entrada del usuario y estará bien.
Esa es la mejor práctica para el rendimiento de todos modos.
Definitivamente, Linq es la forma en que iría en un nuevo proyecto en este momento. Ver esta publicación similar .
fuente
@Keith
Como sugirió Komradekatz, puede prohibir el acceso a las tablas (para el combo de nombre de usuario / contraseña que se conecta a la base de datos) y permitir solo el acceso al SP. De esa manera, si alguien obtiene el nombre de usuario y la contraseña de su base de datos, puede ejecutar SP pero no puede acceder a las tablas ni a ninguna otra parte de la base de datos.
(Por supuesto, ejecutar sprocs puede darles todos los datos que necesitan, pero eso dependería de los sprocs que estuvieran disponibles. Darles acceso a las tablas les da acceso a todo).
fuente
Piénsalo de esta manera
Tiene 4 servidores web y un montón de aplicaciones de Windows que usan el mismo código SQL. Ahora se dio cuenta de que hay un pequeño problema con el código SQl, así que prefiere ... cambiar el proceso en 1 lugar o insertar el código en todos los servidores web, reinstale todas las aplicaciones de escritorio (clickonce podría ayudar) en todos los cuadros de Windows
Prefiero procesos almacenados
También es más fácil hacer pruebas de rendimiento contra un proceso, ponerlo en el analizador de consultas estadísticas del conjunto io / time en set showplan_text on y listo
no es necesario ejecutar el generador de perfiles para ver exactamente cómo se llama
solo mis 2 centavos
fuente
Prefiero mantenerlos en código (usando un ORM, no en línea o ad-hoc) para que estén cubiertos por el control de origen sin tener que lidiar con guardar archivos .sql.
Además, los procedimientos almacenados no son inherentemente más seguros. Puede escribir una consulta incorrecta con un sproc tan fácilmente como en línea. Las consultas en línea parametrizadas pueden ser tan seguras como una sproc.
fuente
Use el código de su aplicación como lo que mejor hace: manejar la lógica.
Utilice su base de datos para lo que mejor hace: almacenar datos.
Puede depurar procedimientos almacenados, pero le resultará más fácil depurar y mantener la lógica en el código. Por lo general, terminará de volver a compilar su código cada vez que cambie el modelo de la base de datos.
Además, los procedimientos almacenados con parámetros de búsqueda opcionales son muy ineficientes porque debe especificar de antemano todos los parámetros posibles y las búsquedas complejas a veces no son posibles porque no puede predecir cuántas veces se repetirá un parámetro en la búsqueda.
fuente
Cuando se trata de seguridad, los procedimientos almacenados son mucho más seguros. Algunos han argumentado que todo acceso será a través de la aplicación de todos modos. Lo que muchas personas están olvidando es que la mayoría de las violaciones de seguridad provienen del interior de una empresa. ¿Piensa en cuántos desarrolladores conocen el nombre de usuario y la contraseña "ocultos" para su aplicación?
Además, como señaló MatthieuF, el rendimiento puede mejorar mucho debido a la menor cantidad de viajes de ida y vuelta entre la aplicación (ya sea en un escritorio o servidor web) y el servidor de la base de datos.
En mi experiencia, la abstracción del modelo de datos a través de procedimientos almacenados también mejora enormemente la mantenibilidad. Como alguien que ha tenido que mantener muchas bases de datos en el pasado, es un gran alivio enfrentar un cambio de modelo requerido para poder simplemente cambiar uno o dos procedimientos almacenados y hacer que el cambio sea completamente transparente para TODAS las aplicaciones externas. Muchas veces su aplicación no es la única que apunta a una base de datos: hay otras aplicaciones, soluciones de informes, etc., por lo que rastrear todos esos puntos afectados puede ser una molestia con el acceso abierto a las tablas.
También pondré verificaciones en la columna más para poner la programación SQL en manos de aquellos que se especializan en ella, y para los SP que hacen que sea mucho más fácil aislar y probar / optimizar el código.
El único inconveniente que veo es que muchos idiomas no permiten el paso de los parámetros de la tabla, por lo que pasar un número desconocido de valores de datos puede ser molesto, y algunos idiomas aún no pueden manejar la recuperación de múltiples conjuntos de resultados de un solo procedimiento almacenado (aunque el este último no hace que los SP sean peores que el SQL en línea a ese respecto).
fuente
Una de las sugerencias de una sesión de Microsoft TechEd sobre seguridad a la que asistí, para hacer todas las llamadas a través de procesos almacenados y denegar el acceso directamente a las tablas. Este enfoque se facturó como proporcionar seguridad adicional. No estoy seguro de si vale la pena solo por seguridad, pero si ya está utilizando procedimientos almacenados, no podría doler.
fuente
Definitivamente más fácil de mantener si lo pones en un procedimiento almacenado. Si hay una lógica difícil involucrada que potencialmente cambiará en el futuro, definitivamente es una buena idea incluirla en la base de datos cuando se conectan varios clientes. Por ejemplo, estoy trabajando en una aplicación en este momento que tiene una interfaz web de usuario final y una aplicación administrativa de escritorio, ambas comparten una base de datos (obviamente) y estoy tratando de mantener tanta lógica en la base de datos como sea posible. Este es un ejemplo perfecto del principio DRY .
fuente
Estoy firmemente del lado de los procesos almacenados, suponiendo que no hagas trampa y uses SQL dinámico en el proceso almacenado. Primero, el uso de procesos almacenados permite que el dba establezca permisos en el nivel de proceso almacenado y no en el nivel de la tabla. Esto es fundamental no solo para combatir los ataques de inyección SQL, sino también para evitar que los iniciados accedan directamente a la base de datos y cambien las cosas. Esta es una forma de ayudar a prevenir el fraude. No se debe acceder a ninguna base de datos que contenga información personal (SSN, números de tarjeta de crédito, etc.) o que de alguna manera cree transacciones financieras, excepto a través de procedimientos almacenados. Si usa cualquier otro método, está dejando su base de datos abierta para que las personas en la empresa creen transacciones financieras falsas o roben datos que pueden usarse para el robo de identidad.
Los procesos almacenados también son mucho más fáciles de mantener y ajustar el rendimiento que el SQL enviado desde la aplicación. También le permiten al dba una forma de ver cuál será el impacto del cambio estructural de una base de datos en la forma en que se accede a los datos. Nunca he conocido a un buen dba que permita el acceso dinámico a la base de datos.
fuente
Utilizamos procedimientos almacenados con Oracle DB's donde trabajo ahora. También usamos Subversion. Todos los procedimientos almacenados se crean como archivos .pkb y .pks y se guardan en Subversion. ¡He hecho SQL en línea antes y es un fastidio! Prefiero la forma en que lo hacemos aquí. Crear y probar nuevos procedimientos almacenados es mucho más fácil que hacerlo en su código.
Hay una
fuente
Troncos más pequeños
Otro pro menor para procedimientos almacenados que no se ha mencionado: cuando se trata del tráfico SQL, el acceso a datos basado en sp genera mucho menos tráfico. Esto se vuelve importante cuando monitorea el tráfico para el análisis y la creación de perfiles: los registros serán mucho más pequeños y legibles.
fuente
No soy un gran admirador de los procedimientos almacenados, pero los uso en una condición:
Cuando la consulta es bastante grande, es mejor almacenarla en la base de datos como un procedimiento almacenado en lugar de enviarla desde el código. De esa manera, en lugar de enviar grandes cantidades de caracteres de cadena desde el servidor de aplicaciones a la base de datos, solo
"EXEC SPNAME"
se enviará el comando.Esto es excesivo cuando el servidor de la base de datos y el servidor web no están en la misma red (por ejemplo, comunicación por Internet). E incluso si ese no es el caso, demasiado estrés significa mucho desperdicio de ancho de banda.
Pero hombre, son tan terribles de manejar. Los evito tanto como puedo.
fuente
Un proceso almacenado SQL no aumenta el rendimiento de la consulta
fuente
Obviamente, el uso de procedimientos almacenados tiene varias ventajas sobre la construcción de SQL en código.
fuente
Los procedimientos almacenados son MÁS mantenibles porque:
¡La repetición de código es lo peor que puede hacer cuando intenta crear una aplicación que se pueda mantener!
¿Qué sucede cuando encuentra un error lógico que debe corregirse en varios lugares? Es más probable que olvides cambiar el último lugar donde copiaste y pegaste tu código.
En mi opinión, las ganancias de rendimiento y seguridad son una ventaja adicional. Todavía puede escribir procedimientos almacenados SQL inseguros / ineficientes.
No es muy difícil escribir todos sus procedimientos almacenados para la creación en otra base de datos. De hecho, es más fácil que exportar sus tablas porque no hay claves primarias / externas de las que preocuparse.
fuente
@Terrapin: los sprocs son igual de vulnerables a los ataques de inyección. Como ya he dicho:
Eso va para sprocs y Sql dinámico.
No estoy seguro de que no recompilar su aplicación sea una ventaja. Quiero decir, has ejecutado tus pruebas unitarias contra ese código (tanto la aplicación como la base de datos) antes de volver a activarlo de todos modos.
@Guy: sí, tienes razón, los sprocs te permiten controlar a los usuarios de la aplicación para que solo puedan realizar el sproc, no la acción subyacente.
Mi pregunta sería: si todo el acceso es a través de su aplicación, utilizando conexiones y usuarios con derechos limitados para actualizar / insertar, etc., ¿este nivel adicional agrega seguridad o administración adicional?
Mi opinión es en gran medida la última. Si han comprometido su aplicación hasta el punto en que pueden reescribirla, tienen muchos otros ataques que pueden usar.
Las inyecciones de SQL todavía se pueden realizar contra esos sprocs si se insertan dinámicamente en el código, por lo que la regla de oro aún se aplica, toda la información del usuario siempre debe parametrizarse.
fuente
Algo que no he visto mencionado hasta ahora: las personas que conocen mejor la base de datos no siempre son las personas que escriben el código de la aplicación. Los procedimientos almacenados brindan a la gente de la base de datos una forma de interactuar con los programadores que realmente no quieren aprender mucho sobre SQL. Las bases de datos grandes, y especialmente las heredadas, no son las cosas más fáciles de entender por completo, por lo que los programadores podrían preferir una interfaz simple que les brinde lo que necesitan: dejar que los DBA descubran cómo unir las 17 tablas para que eso suceda.
Dicho esto, los lenguajes utilizados para escribir procedimientos almacenados (PL / SQL es un ejemplo notorio) son bastante brutales. Por lo general, no ofrecen ninguna de las sutilezas que verías en los imperativos populares, OOP o lenguajes funcionales actuales. Piensa COBOL.
Por lo tanto, se adhieren a los procedimientos almacenados que simplemente abstraen los detalles relacionales en lugar de aquellos que contienen lógica de negocios.
fuente
Generalmente escribo código OO. Sospecho que la mayoría de ustedes probablemente también. En ese contexto, me parece obvio que toda la lógica empresarial, incluidas las consultas SQL, pertenece a las definiciones de clase. Dividir la lógica de manera tal que parte de él reside en el modelo de objetos y parte en la base de datos no es mejor que poner la lógica de negocios en la interfaz de usuario.
Mucho se ha dicho en respuestas anteriores sobre los beneficios de seguridad de los procesos almacenados. Estos se dividen en dos grandes categorías:
1) Restringir el acceso directo a los datos. Esto definitivamente es importante en algunos casos y, cuando te encuentras con uno, los procedimientos almacenados son prácticamente tu única opción. Sin embargo, en mi experiencia, tales casos son la excepción más que la regla.
2) Inyección SQL / consultas parametrizadas. Esta objeción es un arenque rojo. El SQL en línea, incluso el SQL en línea generado dinámicamente, se puede parametrizar tan completamente como cualquier proceso almacenado y se puede hacer con la misma facilidad en cualquier lenguaje moderno que valga la pena. No hay ventaja de ninguna manera aquí. ("Los desarrolladores perezosos podrían no molestarse con el uso de parámetros" no es una objeción válida. Si tiene desarrolladores en su equipo que prefieren concatenar los datos de los usuarios en su SQL en lugar de usar parámetros, primero intente educarlos, luego los despide si eso no funciona, al igual que lo haría con los desarrolladores que tienen cualquier otro hábito malo y demostrablemente perjudicial).
fuente
Soy un gran defensor del código sobre SPROC. La razón número uno es mantener el código estrechamente acoplado, luego un segundo cercano es la facilidad de control de la fuente sin muchas utilidades personalizadas para incorporarlo.
En nuestro DAL si tenemos sentencias SQL muy complejas, generalmente las incluimos como archivos de recursos y las actualizamos según sea necesario (esto también podría ser un ensamblaje separado e intercambiado por db, etc.).
Esto mantiene nuestro código y nuestras llamadas sql almacenadas en el mismo control de versión, sin "olvidar" ejecutar algunas aplicaciones externas para la actualización.
fuente