Pregunta

Suponiendo que no puede usar LINQ por cualquier motivo, ¿es una mejor práctica colocar sus consultas en procedimientos almacenados o es una buena práctica ejecutar? ad hoc ¿Consultas a la base de datos (por ejemplo, SQL Server por razones de argumento)?

¿Fue útil?

Solución

En mi experiencia escribiendo principalmente aplicaciones Cliente/Servidor WinForms, estas son las conclusiones simples a las que he llegado:

Utilice procedimientos almacenados:

  1. Para cualquier trabajo de datos complejo.Si va a hacer algo que realmente requiera un cursor o tablas temporales, generalmente es más rápido hacerlo dentro de SQL Server.
  2. Cuando necesita bloquear el acceso a los datos.Si no otorga acceso a la tabla a los usuarios (o roles o lo que sea), puede estar seguro de que la única forma de interactuar con los datos es a través de los SP que cree.

Utilice consultas ad hoc:

  1. Para CRUD cuando no necesita restringir el acceso a los datos (o lo hace de otra manera).
  2. Para búsquedas sencillas.Crear SP para una serie de criterios de búsqueda es complicado y difícil de mantener.Si puede generar una consulta de búsqueda razonablemente rápida, úsela.

En la mayoría de mis aplicaciones he usado SP y SQL ad-hoc, aunque encuentro que uso cada vez menos SP ya que terminan siendo código como C#, solo que más difíciles de controlar, probar y mantener.Recomendaría usar SQL ad-hoc a menos que pueda encontrar una razón específica para no hacerlo.

Otros consejos

No puedo hablar de nada más que de SQL Server, pero el argumento de rendimiento es no significativamente válido allí a menos que tengas la versión 6.5 o anterior.SQL Server ha estado almacenando en caché planes de ejecución ad hoc durante aproximadamente una década.

Los procedimientos almacenados representan un contrato de software que encapsula las acciones tomadas contra la base de datos.El código de los procedimientos, e incluso el esquema de la propia base de datos, se pueden cambiar sin afectar el código compilado e implementado, de modo que las entradas y salidas del procedimiento sigan siendo las mismas.

Al incorporar consultas en su aplicación, se está acoplando estrechamente a su modelo de datos.

Por la misma razón, tampoco es una buena práctica crear simplemente procedimientos almacenados que sean solo consultas CRUD en cada tabla de su base de datos, ya que esto sigue siendo un acoplamiento estrecho.Los procedimientos deberían ser, en cambio, operaciones voluminosas y de grano grueso.

Desde una perspectiva de seguridad, es una buena práctica no permitir db_datareader y db_datawriter desde su aplicación y solo permitir el acceso a los procedimientos almacenados.

Creo que este es un conflicto básico entre las personas que deben mantener la base de datos y las personas que desarrollan las interfaces de usuario.

Como persona que maneja datos, no consideraría trabajar con una base de datos a la que se accede mediante consultas ad hoc porque son difíciles de ajustar o administrar de manera efectiva.¿Cómo puedo saber qué efecto tendrá un cambio en el esquema?Además, no creo que a los usuarios se les deba otorgar acceso directo a las tablas de la base de datos por razones de seguridad (y no me refiero solo a ataques de inyección SQL, sino también porque es un control interno básico no permitir derechos directos y exigir que todos los usuarios use solo los procesos diseñados para la aplicación.Esto es para prevenir posibles fraudes.Cualquier sistema financiero que permita insertar, actualizar o eliminar derechos directamente en las tablas corre un enorme riesgo de fraude.Esto es algo malo.).

Las bases de datos no están orientadas a objetos y el código que parece bueno desde una perspectiva orientada a objetos puede ser extremadamente malo desde la perspectiva de una base de datos.

Nuestros desarrolladores nos dicen que están contentos de que todo el acceso a nuestra base de datos se realice a través de procesos porque hace que sea mucho más rápido corregir un error centrado en los datos y luego simplemente ejecutar el proceso en el entorno de producción en lugar de crear una nueva rama del código y recompilar y recargar a producción.Requerimos que todos nuestros procesos estén en subversión, por lo que el control de fuente no es un problema en absoluto.Si no está en Subversion, el dbas lo eliminará periódicamente, por lo que no hay resistencia a usar el control de fuente.

Los procedimientos almacenados son definitivamente el camino a seguir... están compilados, tienen un plan de ejecución de antemano y se pueden administrar derechos sobre ellos.

No entiendo todo este problema de control de fuente en el procedimiento almacenado.Definitivamente puedes controlarlos, si eres un poco disciplinado.

Comience siempre con un archivo .sql que sea la fuente de su procedimiento almacenado.Ponlo en control de versiones una vez que hayas escrito tu código.La próxima vez que desee editar su procedimiento almacenado, consígalo desde su control de fuente en lugar de su base de datos.Si sigue esto, tendrá un control de fuente tan bueno como su código.

Me gustaría citar a Tom Kyte de Oracle aquí... Aquí está su regla sobre dónde escribir código... aunque no tiene nada que ver, pero es bueno saberlo, supongo.

  1. Comience con procedimientos almacenados en PL/SQL...
  2. Si cree que no se puede hacer algo usando el procedimiento almacenado en PL/SQL, use el procedimiento almacenado de Java.
  3. Si cree que no se puede hacer algo utilizando el procedimiento almacenado de Java, considere Pro*c.
  4. Si cree que no puede lograr algo usando Pro*C, es posible que desee reconsiderar lo que necesita hacer.

En nuestra aplicación, hay una capa de código que proporciona el contenido de la consulta (y, a veces, es una llamada a un procedimiento almacenado).Esto nos permite:

  • tener fácilmente todas las consultas bajo control de versiones
  • para realizar los cambios necesarios en cada consulta para diferentes servidores de bases de datos
  • elimina la repetición del mismo código de consulta en todo nuestro código

El control de acceso se implementa en la capa intermedia, en lugar de en la base de datos, por lo que no necesitamos procedimientos almacenados allí.En cierto modo, este es un camino intermedio entre las consultas ad hoc y los procesos almacenados.

Mi respuesta de un diferente correo:Los procedimientos almacenados son MÁS mantenible porque:

  • No es necesario que vuelvas a compilar tu aplicación C# cada vez que quieras cambiar algo de SQL.
  • Terminas reutilizando el código SQL.

La repetición de código es la el peor ¡Lo que puedes hacer cuando intentas crear una aplicación mantenible!

¿Qué sucede cuando encuentra un error lógico que debe corregirse en varios lugares?Es más probable que te olvides de cambiar el último lugar donde copiaste y pegaste tu código.

En mi opinión, las mejoras en rendimiento y seguridad son una ventaja adicional. Aún puede escribir procedimientos almacenados SQL inseguros/ineficientes.

Más fácil de portar a otra base de datos: no hay procesos para portar

No es muy difícil escribir todos los procedimientos almacenados para crearlos 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.

Hay argumentos convincentes para ambos: todos los procedimientos almacenados están ubicados en un repositorio central, pero son (potencialmente) difíciles de migrar y las consultas ad hoc son más fáciles de depurar como lo son con su código, pero también pueden ser más difíciles de encontrar en el código.

El argumento de que los procedimientos almacenados son más eficientes ya no se sostiene.Texto del enlace

Hacer una búsqueda en Google para Procedimiento almacenado versus consulta dinámica mostrará argumentos decentes de cualquier manera y probablemente sea mejor para que usted tome su propia decisión...

Los procedimientos de la tienda deben usarse tanto como sea posible, si al escribir SQL en el código ya se está preparando para sufrir dolores de cabeza en el futuro.Se necesita aproximadamente el mismo tiempo para escribir un SPROC que para escribirlo en código.

Considere una consulta que se ejecuta muy bien con una carga media, pero una vez que entra en producción a tiempo completo, su consulta mal optimizada golpea el sistema y lo arrastra.En la mayoría de los servidores SQL, usted no es la única aplicación/servicio que lo utiliza.Su solicitud ha atraído a un grupo de personas enojadas a su puerta.

Si tiene sus consultas en SPROC, también permite que su amigable DBA administre y optimice sin recompilar ni romper su aplicación.Recuerde que los DBA son expertos en este campo, saben qué hacer y qué no hacer.¡Tiene sentido utilizar su mayor conocimiento!

EDITAR:¡Alguien dijo que recompilar es una excusa perezosa!Sí, veamos qué tan vago te sientes cuando tienes que recompilar e implementar tu aplicación en miles de escritorios, ¡todo porque el DBA te ha dicho que tu consulta ad-hoc está consumiendo demasiado tiempo del servidor!

¡Alguien dijo que recompilar es una excusa perezosa!Sí, veamos qué tan vago te sientes cuando tienes que recompilar e implementar tu aplicación en miles de escritorios, ¡todo porque el DBA te ha dicho que tu consulta ad-hoc está consumiendo demasiado tiempo del servidor!

¿Es una buena arquitectura del sistema si permite conectar 1000 escritorios directamente a la base de datos?

Algunas cosas para pensar aquí: De todos modos, ¿quién necesita procedimientos almacenados?

Claramente es una cuestión de sus propias necesidades y preferencias, pero una cosa muy importante en la que pensar al utilizar consultas ad hoc en un entorno público es la seguridad.Parametricéelos siempre y tenga cuidado con las vulnerabilidades típicas como Ataques de inyección SQL.

Los procedimientos almacenados son excelentes porque se pueden cambiar sin necesidad de volver a compilar.Intentaría utilizarlos con la mayor frecuencia posible.

Solo uso ad-hoc para consultas que se generan dinámicamente en función de la entrada del usuario.

Procs por las razones mencionadas por otros y también es más fácil ajustar un proceso con perfilador o partes de un proceso.De esta manera, no es necesario que le diga a alguien que ejecute su aplicación para saber qué se envía al servidor SQL.

Si utiliza consultas ad-hoc, asegúrese de que estén parametrizadas

SQL parametizado o SPROC... no importa desde el punto de vista del rendimiento... puede optimizar cualquiera de los dos.

Para mí, el último beneficio restante de un SPROC es que puedo eliminar gran parte de la administración de derechos de SQL al otorgarme solo derechos de inicio de sesión para ejecutar sprocs... si usa SQL parametizado, el inicio de sesión dentro de su cadena de conexión tiene muchos más derechos (escribiendo CUALQUIER tipo de declaración de selección en una de las tablas a las que también tienen acceso, por ejemplo).

Aunque sigo prefiriendo SQL parametizado...

No he encontrado ningún argumento convincente para utilizar consultas ad-hoc.Especialmente aquellos mezclados con su código C#/Java/PHP.

El argumento del rendimiento de sproc es discutible: los 3 RDBM principales usan almacenamiento en caché del plan de consultas y lo han estado haciendo por un tiempo.Ha sido documentado...¿O todavía es 1995?

Sin embargo, incorporar SQL en su aplicación también es un diseño terrible: el mantenimiento del código parece ser un concepto faltante para muchos.

Si una aplicación puede comenzar desde cero con un ORM (¡las aplicaciones totalmente nuevas son muy pocas!), es una excelente opción ya que su modelo de clase impulsa su modelo de base de datos y ahorra MUCHO tiempo.

Si no hay un marco ORM disponible, hemos adoptado un enfoque híbrido para crear un archivo XML de recursos SQL para buscar cadenas SQL a medida que las necesitamos (luego el marco de recursos las almacena en caché).Si SQL necesita alguna manipulación menor, se realiza en código; si se necesita una manipulación importante de la cadena SQL, repensamos el enfoque.

Este enfoque híbrido facilita la administración por parte de los desarrolladores (tal vez seamos la minoría ya que mi equipo es lo suficientemente inteligente como para leer un plan de consulta) y la implementación es un simple pago desde SVN.Además, facilita el cambio de RDBM: simplemente intercambie el archivo de recursos SQL (no es tan fácil como una herramienta ORM, por supuesto, pero conectarse a sistemas heredados o bases de datos no compatibles funciona).

Depende de cuál sea tu objetivo.Si desea recuperar una lista de elementos y esto sucede una vez durante toda la ejecución de su aplicación, por ejemplo, probablemente no valga la pena el esfuerzo de utilizar un procedimiento almacenado.Por otro lado, una consulta que se ejecuta repetidamente y tarda (relativamente) mucho tiempo en ejecutarse es una excelente candidata para el almacenamiento de una base de datos, ya que el rendimiento será mejor.

Si su aplicación reside casi por completo dentro de la base de datos, los procedimientos almacenados son una obviedad.Si está escribiendo una aplicación de escritorio para la cual la base de datos sólo es tangencialmente importante, las consultas ad hoc pueden ser una mejor opción, ya que mantiene todo su código en un solo lugar.

@Tortuga de agua dulce:Creo que su afirmación de que el hecho de que no tenga que volver a compilar su aplicación para realizar modificaciones hace que los procedimientos almacenados sean una mejor opción no es viable.Puede haber razones para elegir procedimientos almacenados en lugar de consultas ad hoc, pero en ausencia de algo más convincente, el problema de compilación parece más pereza que una razón real.

Mi experiencia es que el 90% de las consultas y/o procedimientos almacenados no deberían escribirse en absoluto (al menos a mano).

El acceso a los datos debería generarse de alguna manera automáticamente.Puede decidir si desea generar procedimientos estáticamente en tiempo de compilación o dinámicamente en tiempo de ejecución, pero cuando desee agregar una columna a la tabla (propiedad del objeto), debe modificar solo un archivo.

Prefiero conservar todos los datos. acceso Lógica en el código del programa, en la que la capa de acceso a datos ejecuta consultas SQL directas.Por otra parte, datos gestión Lógica que puse en la base de datos en forma de activadores, procedimientos almacenados, funciones personalizadas y todo eso.Un ejemplo de algo que considero digno de incluir en la base de datos es la generación de datos: supongamos que nuestro cliente tiene un nombre y un apellido.Ahora, la interfaz de usuario necesita un DisplayName, que se deriva de alguna lógica no trivial.Para esta generación, creo un procedimiento almacenado que luego se ejecuta mediante un disparador cada vez que se actualiza la fila (u otros datos de origen).

Parece haber un malentendido algo común de que la capa de acceso a datos ES la base de datos y todo lo relacionado con los datos y el acceso a los datos va allí "sólo porque sí".Esto es sencillamente incorrecto, pero veo muchos diseños que se derivan de esta idea.Aunque quizá se trate de un fenómeno local.

Es posible que simplemente me haya desanimado la idea de los SP después de ver tantos mal diseñados.Por ejemplo, un proyecto en el que participé utilizó un conjunto de procedimientos almacenados CRUD para cada tabla y cada consulta posible que encontraron.Al hacerlo, simplemente añadieron otra capa completamente inútil.Es doloroso incluso pensar en esas cosas.

Hoy en día casi nunca uso procedimientos almacenados.Sólo los uso para consultas SQL complicadas que no se pueden realizar fácilmente en código.

Una de las razones principales es que los procedimientos almacenados no funcionan tan bien con los mapeadores OR.

Hoy en día creo que se necesita una muy buena razón para escribir una aplicación empresarial/sistema de información que no utilice algún tipo de mapeador OR.

El procedimiento almacenado funciona como un bloque de código, por lo que en lugar de una consulta ad hoc, funciona rápidamente.Otra cosa es el procedimiento almacenado, dar la opción de recompilar que la mejor parte de SQL solo usa esto para procedimientos almacenados nada como esto en la consulta Adhoc.

Algunos resultados en la consulta y el procedimiento almacenado son diferentes, esa es mi experiencia personal.Utilice la función de transmisión y encubrimiento para comprobar esto.

Debe utilizar un procedimiento almacenado para grandes proyectos para mejorar el rendimiento.

Tenía 420 procedimientos en mi proyecto y me funciona bien.Trabajo durante los últimos 3 años en este proyecto.

Por lo tanto, utilice únicamente procedimientos para cualquier transacción.

¿Es una buena arquitectura del sistema si deja conectar 1000 escritorios directamente a la base de datos?

No, obviamente no lo es, tal vez sea un mal ejemplo, pero creo que el punto que estaba tratando de dejar claro es que su DBA cuida la infraestructura de su base de datos, es decir, donde está su experiencia, incluir SQL en el código cierra la puerta a ellos y a su experiencia.

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