visual studio español ejecutar conectar code sql

studio - SQL vs CODE, ¿Dónde está el saldo?



visual studio code mysql (27)

Depende del tipo de aplicación. Si la aplicación es la única que está usando la base de datos, entonces el código es el maestro. Si el DB es probable que sobreviva a la aplicación, entonces use DB tanto como sea posible.

Como desarrollador de CRUD, una de las compensaciones que debe realizarse es la decisión de qué parte del trabajo se debe hacer en SQL en el servidor y cuánto debe hacerse en el extremo del cliente en el código.

¿Cómo decides dónde va el fulcro? ¿Qué factores entran en tus decisiones? ¿Qué tipo de errores has cometido? ¿Qué funciona bien?

[EDITAR] Estoy un poco sorprendido por el bajo volumen de respuestas a esta pregunta. Creo que este es un problema básico para toda la programación de CRUD. Donde se establece el equilibrio es una compensación entre el rendimiento y la capacidad de mantenimiento.

El otro problema que realmente no consideré es el hecho de que los dominios varían lo suficiente, que las respuestas probablemente deban expresarse en secciones para cada dominio. Eso es lo que intenté hacer en mi respuesta.


En mi experiencia, es más fácil realizar una validación compleja de los datos en código que en SQL, por lo que la respuesta está en el tipo de aplicación y datos con los que estoy tratando. Si la validación necesaria es bastante benigna, no tengo problemas para poner esta lógica en el nivel de la base de datos en forma de procedimientos almacenados.

Sin embargo, una desventaja definitiva de este enfoque ocurre cuando las actualizaciones a su aplicación son necesarias. Los cambios en el esquema pueden ser más difíciles de implementar que los cambios en el código del lado del cliente, especialmente si envía código a los clientes en lugar de desarrollar aplicaciones para uso interno.

Además, generalmente requiere más trabajo armar scripts de cambio para cambios en el esquema de la base de datos (por ejemplo, identificar objetos cambiados, hacer que los scripts de cambio sean idempotentes) en comparación con realizar una compilación del código de la aplicación. Esto se debe principalmente a las herramientas (o la falta de ellas) disponibles en el lado del desarrollo de la base de datos.


En mi opinión, si se trata directamente de datos, entonces debe hacerse en la base de datos; si se trata de lógica comercial, debe hacerse en código.

Por ejemplo, el filtrado de datos por un campo específico debe corresponder a la base de datos. La agregación de totales para mostrar en un informe debe hacerse en la base de datos. La menor lógica relacionada con los datos (por ejemplo, desencadenadores que hacen cumplir la integridad de los datos) debe hacerse en ambos (¡no me critique por ese comentario!) Para asegurarse de que su aplicación sea segura.

La lógica comercial real, como aplicar un descuento si el total del pedido es superior a $ 500, debe hacerse en código y tener el valor final solo almacenado en la base de datos. Sin embargo, si el monto del descuento varía en función del tipo de cliente, el monto del descuento debe almacenarse en la base de datos, pero no la lógica que realiza el cálculo.


Intento hacer cosas de base de datos en la base de datos. por lo tanto, ordenar, agrupar, filtrar. eso está todo hecho en la consulta (generalmente un sproc). Uso el código para ejecutar la consulta y luego hago todo lo que necesito para el código. También trato de emplear la mentalidad "obtener los datos una vez, y solo una vez" cuando es prudente para reducir los viajes de ida y vuelta al servidor.


Mi decisión de código frente a sql depende típicamente de cuál parece la forma más fácil / más rápida de implementar. Una vez que está allí, sigo adelante. Más tarde, si parece que se debe mover, se mueve. < shrug > Sin embargo, trato de no sudar demasiado al principio.

Si se trata de algo fuertemente vinculado a la base de datos, especialmente algo que implica mucho trabajo con los registros de la base de datos, simplemente tiene sentido entrar en sql. Si se trata de algo estrechamente ligado a la aplicación, va allí.


Normalmente, en los proyectos en los que he estado involucrado, la mayoría de los datos son manejados por el servidor de la base de datos, y la mayor parte de la presentación se realiza con el código.

La excepción es esta: SELECCIONAR tabla col1, col2, col3 FROM

La presentación es: col1, col2, col3, col1 / col2, col1 / col3, ...

Si obtengo todos los operandos en una ecuación, lo haré en el código; si no, lo haré como parte de la consulta (seleccione col1, col2, col1 / col4 ...)


Para mí, las bases de datos son una necesidad debido a una limitación tecnológica: la memoria principal es pequeña y no persiste. Entonces, para mí, todo lo que no está relacionado con la persistencia está en el código, solo cuando necesito obtener datos de ida y vuelta recurro a SQL (en realidad ni siquiera eso, mi DAL hace eso por mí).


Todo lo que se relacione con la integridad de los datos se debe hacer en la base de datos. La razón de esto es que los datos pueden verse afectados por varias fuentes, no solo por la interfaz de usuario. Por lo tanto, las bases de datos deben almacenar las relaciones clave, las restricciones sobre los datos permitidos en un campo, los valores predeterminados, etc. Los desencadenadores son obligatorios si las restricciones son demasiado complejas para una restricción regular. Los tipos de datos deben ser cuidadosamente pensados ​​y servir de alguna manera como restricciones. Si los datos están destinados a ser utilizados en cálculos matemáticos, debe usarse algún tipo de tipo de datos numéricos (no flotante o real), si los datos son una fecha, siempre use un tipo de datos de fecha y hora para evitar que se almacenen las fechas. Si los datos son numéricos pero no están destinados a cálculos matemáticos (SSN, por ejemplo), almacénelos en un tipo de cadena de datos pero aplique una restricción para asegurarse de que todos los valores almacenados sean números.

Esto no significa que no deba verificar si es una fecha válida en la GUI antes de enviarla. Debe realizar comprobaciones de los datos que la GUI envía a la base de datos para evitar enviar datos que no se insertarán, pero la base de datos siempre debe estar configurada para evitar que se inserten datos incorrectos sin importar cómo se envíen. No tiene sentido gastar valiosos recursos de base de datos y netwrok procesando datos malos conocidos.

La agregación de informes a menudo se puede realizar más rápido en la GUI, pero si se deben devolver demasiados registros, puede ser mejor hacerlo en el lado de la base de datos o se debe crear una base de datos de informes OLAP para aumentar la velocidad.


Una base de datos es un lugar para almacenar tablas de filas multimillonarias, para leer y escribir eficazmente en esas tablas.

Una base de datos no es un lugar para realizar manipulación de cadenas o lógica de fechas. No es un lugar para calcular saldos o generar correos. Estas preocupaciones se abordan mejor con otras herramientas (como el código).


Dentro de nuestro grupo hay un par de casos.

Procesamiento que puede ser satisfecho con INSERT / SELECT

En general, tenemos el programa escribir la inserción de seleccionar, en función de los parámetros proporcionados por el usuario, que luego se ejecutan en el servidor

Control de interrupción de procesamiento

El programa crea la selección, con el orden requerido por, y la ejecuta en el contexto del servidor. El conjunto de resultados se absorbe nuevamente en el programa y se procesa como una interrupción de control, fila por fila.

Procesamiento complejo

El programa crea la selección y la ejecuta en el contexto del servidor. El conjunto de resultados se absorbe de vuelta al programa, fila por fila, donde se produce un procesamiento intensivo de código. El resultado va a un archivo o UPSERT a la base de datos.

Rendimiento crítico

El programa crea la selección y la ejecuta en el contexto del servidor. El conjunto de resultados completo vuelve a la memoria, donde se produce un procesamiento intensivo de código. La información procesada resultante se guarda en un archivo o se vuelve a enviar a la base de datos.


  1. Acceda a la base de datos el menor número de veces posible.

  2. Si termina descartando datos recuperados de la base de datos, su consulta debe ser revisada y hecha más específica.

  3. El script es responsable de manipular los datos, a menos que exista un índice que lo haga más fácil para la base de datos.

  4. La base de datos debería poder existir sin una secuencia de comandos. Los trabajos de Cron son agradables, pero una base de datos debería poder sobrevivir si un script no se ejecuta en un momento específico.

  5. Nunca coloque una consulta en un bucle. Siempre hay una manera de producir el mismo resultado en una consulta (también conocido como join).

  6. La base de datos solo existe para contener y recuperar datos sin procesar lo más rápido posible. Deje cualquier formato o matemática para el guión.

Para concluir, enfatice la base de datos el menor número de veces posible. Utilice la menor cantidad posible de consultas relacionadas con la inserción y recuperación de datos. Haga que el script lleve más carga, y asegúrese de que la base de datos no sea la primera en bajar.


Debido a que mi código se ejecuta en las computadoras de mis clientes y no quiero necesitar el acceso de administrador de la base de datos solo para actualizar mi código, no puse casi nada en la base de datos, excepto los datos.


El saldo es el punto en el que obtiene la máxima capacidad de mantenimiento con un rendimiento aceptable.

Toda la lógica comercial debe hacerse dentro de la aplicación. Puede comenzar con el servidor Sql, pero si la política cambia a Oracle. Simplemente migre sus datos a Oracle y no necesita volver a escribir ningún código.

O algunas aplicaciones, deben admitir múltiples db, por lo que acabas de completar todos los códigos en la aplicación. Cuando tienes problemas, solo arreglas problemas solo en la aplicación. No es necesario solucionar problemas en múltiples db.

Para hacer esto, todos los códigos CRUD se deben generar dentro de la aplicación. Eso significa que necesita un buen marco ORM (Linq, Hibernate) para hacer el trabajo.


Estamos utilizando .NET 3.5 y LINQ to SQL, por lo que somos 100% de código y no tenemos ningún SQL escrito a mano. ¡Es una dicha!


Estas son algunas de las compensaciones que consideraría:

  • Conjunto versus manipulación de datos individuales
  • Grandes o pequeñas cantidades de datos
  • Secreto contra bits no secretos (código abierto)
  • Objetivos de plataforma db individuales frente a múltiples
  • Posiblemente código de biblioteca reutilizado o proyecto específico
  • Conjunto de habilidades SQL desarrollador vs código

... Te dejaré saber si pienso en otra cosa.


La única respuesta sensata a esta pregunta es, depende.


Mis reglas para cuando usar sql:

No realice una llamada a la base de datos al recorrer un conjunto de registros.

Mantenga su lógica unida

Piensa en los otros desarrolladores que vendrán detrás de ti. Escríbalo en el lugar en el que será más claro.


No estoy seguro de que mis experiencias respondan a su pregunta, pero esto es lo que hacemos en caso de que sea útil.

Tenemos un procedimiento almacenado para ACTUALIZAR. Tiene un parámetro para Debe existir, No debe existir o No importa. Entonces, si un operador está usando un proceso CREATE, el registro debe ser nuevo; si usa un proceso MODIFY, entonces la cuenta debe existir; si haces algún tipo de importación, tal vez quieras un UpSert , en cuyo caso no te importa.

Nuestras aplicaciones se basan en la web, por lo que los datos proceden de formularios web. Los campos de formulario contendrán datos o serán cadenas vacías. Puede haber otros campos, en el registro, que no están en el formulario.

Nuestro procedimiento de actualización tiene parámetros para cada campo de la tabla, los parámetros predeterminados son NULL, excepto los campos PK que se deben proporcionar :)

Por lo tanto, se proporcionará un campo de cadena vacío para el procedimiento, y los campos que no están en el formulario no lo harán, y se establecerán por defecto en NULL. No se permite pasar un campo de formulario como NULL: todos los campos que estaban en el formulario deben pasar un valor.

Para los registros existentes, al estar actualizados, tratamos a NULL como "sin cambios" y un valor como causante de un cambio. Sin embargo, no permitimos el almacenamiento de cadenas vacías, por lo que pasar un parámetro de una cadena vacía hace que el campo en ese registro cambie a NULL. (Particularmente relevante para los tipos de fecha, por ejemplo, ya que solo se pueden almacenar fechas válidas, no cadenas vacías, y la cadena vacía para un número probablemente se tratará como cero si no aplicamos esta regla)

Esto nos ha funcionado y nos ha permitido generar mecánicamente dichos procedimientos de base de datos y los formularios relevantes asociados con ellos.

Además, permitimos que el Procedimiento de Actualización devuelva un código de Error de Validación. En general, la aplicación lleva a cabo la validación de los campos del formulario, en primer lugar, utilizando Javascript en el Cliente para exigir que las fechas sean válidas, y así sucesivamente; en segundo lugar, la aplicación puede aplicar las mismas (para seguridad) y validaciones adicionales. Y, finalmente, el procedimiento de la base de datos puede realizar más validaciones, por ejemplo, para verificar que un artículo de pedido tenga un registro de encabezado de pedido correspondiente; aunque esto también se aplica mediante una restricción de clave externa, no nos gusta tener que capturar (e interpretar) el error de base de datos resultante, por lo que el procedimiento de actualización comprueba y devuelve un número / mensaje de error que es útil para la aplicación (y corresponde a un mensaje, mantenido en una tabla de errores, que se puede mostrar al operador para que sepan cuál fue el problema). La restricción de clave externa todavía está en su lugar como un receptor de parada larga.

También generamos mecánicamente el procedimiento Get / Read. Esto devuelve todos los campos para una sola fila. El parámetro para el procedimiento son todos los campos PK. Esto puede ser utilizado por los formularios CRUD para obtener cualquier información existente. Usamos esto, en lugar de un procedimiento específico para cada formulario, con el conocimiento de que recupera todas las columnas y algunas de ellas pueden no ser necesarias en el formulario específico. Es solo una recuperación de fila única, y la probabilidad es que todos los campos se representarán en el formulario de mantenimiento CRUD. Sin embargo, según la regla 80:20 ri, somos más circunspectos en los formularios para los registros que tienen columnas de texto que no están en el formulario, claramente, recuperar muchos datos que no están en el formulario no es bueno. Para el resto, creemos que la coherencia de la programación, y teniendo relativamente pocas excepciones, reduce los errores y el ahorro de costos supera cualquier dato adicional recuperado.

Este enfoque también significa que a medida que el esquema de la base de datos cambia, los Procedimientos están en línea con los cambios, y sacarán a la luz los problemas que esto ahora causa con los formularios existentes. Por ejemplo, si se cambia el nombre de una columna, el formulario fallará inmediatamente, al intentar llamar al procedimiento con un parámetro que ya no es válido o al utilizar una columna que ya no se recupera. Podemos aislar esto cuando sea necesario para compatibilidad con versiones anteriores: permitir que el procedimiento de Actualización tenga un parámetro adicional con el nombre original y COALESCE que con el parámetro que representa el nuevo nombre de la columna, y tener las columnas Get / Read return duplicate en el conjunto de resultados con ambos Nuevos y viejos nombres.

Del mismo modo para Eliminar. El procedimiento se genera mecánicamente, toma el PK como un parámetro y tiene la capacidad de devolver un mensaje de Validación (por ejemplo, cuando se intenta eliminar el Encabezado del pedido si aún tiene registros del Artículo de pedido hijo).

Todas nuestras tablas tienen campos para Creador, Crear fecha, Actualizador, Fecha de actualización y también un EditNo, que se incrementa cada vez que se guarda el registro. El valor EditNo se le da al formulario (en un campo de entrada oculto) y, por lo tanto, se pasa al procedimiento Update o Delete. Debe coincidir con el valor del registro existente; de ​​lo contrario, el registro ha sido cambiado por otro operador y la última actualización es rechazada (nuevamente, los procedimientos de actualización proporcionan un mensaje útil al operador, incluyendo quién era el otro actualizador y en qué momento).

Para la mayoría de las tablas de datos también tenemos una tabla de archivo. Esto almacena una copia del registro "anterior" cuando se realiza una actualización. No almacenamos el nuevo registro porque está en la tabla principal y, por lo tanto, reducimos la cantidad de datos que almacenamos en el archivo.

Esto tiene todas las columnas en el registro principal, más una Acción - Actualizar o Eliminar - y la Fecha de Auditoría. Los registros se insertan en el archivo mediante un disparador de actualización / eliminación en la tabla principal.

También tenemos procedimientos de búsqueda generados mecánicamente. Estos tienen parámetros que coinciden con los campos de la tabla, pero pueden ser para puntos de inicio / finalización (por ejemplo, un intervalo de fechas de pedido), una coincidencia exacta o una coincidencia "contiene", como "Nombre como XXXX". Estos devuelven solo los campos específicos que realmente utiliza la pantalla, y el procedimiento generado mecánicamente tiene una cláusula WHERE adecuada utilizando los parámetros definidos. En la práctica, estos procedimientos se cambian manualmente para optimizarlos a mano, etc., pero son útiles cuando se hace una aplicación para proporcionar un comienzo de vuelo para la consulta de los datos por parte del usuario.


SQL es un código especializado adecuado para manipular conjuntos de datos, como clasificar, filtrar y unir. Creo que "SQL vs. CODE" es una pregunta engañosa. En cambio, sugiero ver su problema como una opción entre múltiples idiomas especializados. Para esta respuesta, usaré el término "lado del servidor" para referirme al código SQL y "del lado del cliente" para referirme a todo lo escrito en un lenguaje diferente y más general.

En mi experiencia, el código del lado del cliente es más fácil de escribir y mantener porque (1) tiendo a estar más familiarizado con el lenguaje y las herramientas del lado del cliente, (2) el desarrollo del lado del cliente tiende a tener mejores herramientas, editores y fuentes -control de integración, y (3) el mantenimiento es más fácil porque solo necesito buscar la lógica en un solo lugar. Por lo tanto, prefiero escribir el código del lado del cliente en lugar del código del lado del servidor, a menos que tenga una razón convincente para hacerlo.

Pero, el código del lado del servidor, en forma de instrucciones SQL, es esencial para un rendimiento adecuado. Los datos de unión, filtrado y clasificación casi siempre pertenecen a SQL porque la base de datos lo hará más rápido y más fácil de lo que puede hacer en el lado del cliente. Como regla general, si estoy escribiendo código que utiliza cursores SQL para filtrar u ordenar conjuntos de registros, probablemente estoy haciendo algo mal y debería mover esa lógica a SQL, donde será más rápido, más fácil de escribir y más fácil de usar. entender.


Si hacerlo en SQL lo hace más manejable, hazlo en SQL. Si hacerlo en código lo hace más manejable, hazlo en código.


Esto es menos una pregunta de SQL vs. Código, y más de una pregunta de Cliente vs. Servidor. La idea completa de Cliente / Servidor es permitir que el servidor brinde un servicio a los clientes de manera centralizada. En la práctica esto significa:

  • Si el servidor puede hacerlo rápidamente, entonces hazlo en el servidor
  • Si el servidor puede devolver un pequeño resultado, hágalo en el servidor
  • Si puede ocultar la complejidad del cliente, hágalo en el servidor

Muchos de los problemas involucrados se encuentran en otras áreas de diseño, como el diseño orientado a objetos. Una clase que proporciona servicios a otras clases debe encapsular la funcionalidad y solo exponer lo que necesitan sus clientes. Lo mismo ocurre con un servidor SQL. Si está pensando en un servidor SQL como un mero sistema de recuperación de datos, entonces no está tomando la ventaja adecuada.

Los ahorros prácticos incluyen: minimizar los datos enviados a través de la red; proceso de centralización / estandarización; permitiendo cambios sin volver a implementar el software del cliente; desempeño mejorado.

En cuanto a dónde exactamente dibujar la línea ... no hay una respuesta mágica. La verdadera respuesta es que el esquema de la base de datos + procedimientos almacenados + vistas definen una API, y un buen diseño de la API no es trivial, pero vale la pena la molestia. Use principios como ocultamiento de información, encapsulado, cohesión y todas esas otras cosas que usa en el resto de su trabajo de programación y diseño. Ellos son apropiados aquí.


¿Qué tienes?

  • Grandes desarrolladores de bases de datos que pueden generar procs y visualizaciones almacenadas complejas y eficientes y mantener la integración de datos con claves externas diseñadas con buen diseño y tablas debidamente normalizadas.

O

  • Grandes codificadores que dominaron el lenguaje y los marcos utilizados para desarrollar la aplicación.

Si la respuesta a lo anterior es DB, los desarrolladores son su punto fuerte, entonces haga el trabajo en la base de datos. Un tipo DB realmente bueno puede proporcionar la funcionalidad para que su código pueda ser completamente simple. Podrían ser algunos viajes de ida y vuelta (y eso puede ser fatal en algunas situaciones) pero el rendimiento puede ser muy bueno. El gran problema es que no hay muchos DB realmente talentosos alrededor.

Si su punto fuerte es la codificación, mantenga el DB simple y use consultas parametrizadas muy simples para obtener y actualizar su db. Solo use cosas como desencadenantes y procedimientos almacenados cuando golpee el cuello de una botella. Tienes que tener alguna habilidad en la administración de DB. Cosas básicas como decidir sobre el índice y el mantenimiento de esos índices. También saber cuándo normalizar y cuándo NO es necesario.


Aquí hay un consejo que escuché en este sentido: si un proyecto tiene un presupuesto de menos de $ 1 millón, coloque declaraciones SQL en el código del cliente. Si el presupuesto es superior a $ 1 millón, cree clases de acceso, etc. Consulte esta publicación en el blog . No sé si estoy de acuerdo con el monto específico en dólares, pero estoy de acuerdo en que el presupuesto (y el tamaño implícito del proyecto, importancia, etc.) debe influir en la forma formal en que se encuentre en su desarrollo.


La respuesta es impulsada por la fuerza de los desarrolladores involucrados. Al final, debe ser productivo, por lo que debe equilibrar los problemas actuales con consideraciones de mantenimiento a largo plazo Y teniendo en cuenta que su equipo puede ser todos los desarrolladores de aplicaciones y no SQL pesados.

¿Cómo vas a comunicar los cambios al equipo, y qué pueden entender todos contra el chico de la esquina al que siempre vas a correr y que jugará genial durante los próximos años? Si su código vuelve con errores, ¿con qué rapidez puede cada miembro del equipo obtener la raíz del problema?

Todo lo que dijo la "administración", hay algunos conceptos básicos que otros han detallado aquí y que haré eco también:

  • La falta de un buen diseño de base de datos no se puede superar la complejidad fría en el código
  • Integridad de datos es el trabajo de la base de datos
  • Resuelva problemas complejos con código de procedimiento. No hay nada como leer bien, código de estructura.
  • Los informes de objetos de dominio pueden ser extremadamente difíciles, y el conjunto de habilidades para redactar informes generalmente coincide con una mayor experiencia de DB, no con DDD.

Realicé la programación de CRUD como asesor durante más de 10 años en el mundo de los negocios. Puedo decirte que pongo tanta lógica comercial en sprocs y views como puedo (y tiene sentido). Los requisitos tienden a cambiar cada vez que los vientos soplan y tener lógica en la base de datos facilita el cambio y (con comentarios decentes) se autodiagnostica. Además, los sprocs ofrecen una buena seguridad y una fácil reutilización del código. En los negocios, sprocs SON la aplicación.


Utilizo SQL para consultas (declarativo) y Python para procedimientos (operaciones paso a paso).


Mis prioridades:

  1. Minimice los viajes a la base de datos. El código debería hacer la mayor parte del trabajo, si es posible, y solo visitar la base de datos cuando sea necesario. Cuando lo haga, debería obtener tanto como sea necesario para la operación actual como sea posible.

  2. Minimiza la complejidad de SQL. Aunque deberíamos visitar menos la base de datos, esto no significa construir una consulta SQL demasiado compleja que no sea eficiente y que haga demasiado. La consulta aún tendrá que mantenerse, y si dos consultas más simples le ahorrarán el dolor de cabeza de desarrollar y mantener una mega-consulta, entonces se debe usar código adicional en lugar de más trabajo en la base de datos.

  3. Minimice la iteración de la lista de códigos. El código es genial. Un buen lugar para poner la lógica de negocios y muchas funciones ordenadas de biblioteca. El código es asombroso Pero si usar código significa tener que iterar una y otra vez a través de listas devueltas desde la base de datos donde algunas bases de datos simples donde las cláusulas o las uniones podrían haber eliminado ese trabajo, entonces el SQL necesita ser mejorado y el código minimizado.

Generalmente es caso por caso. Para aplicaciones de larga duración, el mantenimiento es un gran costo y la simplicidad a menudo dictará mi diseño.