¿La mejor manera de organizar consultas SQL almacenadas en su código? (¿o deberías?) [cerrado]

13

Estoy seguro de que no soy el único que se frustra cuando ven una página de código llena de consultas SQL. El ActiveRecord y otros patrones ORM ayudan a mitigar una buena cantidad de SQL utilizado en un proyecto, pero en muchos casos de consultas complejas, el uso de SQL es aparentemente inevitable.

¿Estoy buscando opiniones sobre cómo deberían organizarse las consultas SQL con el resto del código (o externamente) para evitar que se dispersen por todo el lugar? Una idea obvia es el uso de Vistas, pero a menudo las Vistas pueden ser una fuente de problemas de rendimiento cuando se trata de múltiples tablas indexadas grandes, etc.

EDITAR 1 - Supongo que ya lo tienes separado en la capa del modelo

jellyfishtree
fuente
3
Esta pregunta es definitivamente apropiada aquí: organización del código: 'inspirar [s] respuestas que explican "por qué" y "cómo". y es de los temas 'Patrones de diseño' y 'Arquitectura' (de las preguntas frecuentes )
Michael K
1
Estaba a punto de hacer esta misma pregunta. Desearía que hubiera más respuestas aquí.
Michael Kristofik

Respuestas:

10

Para mí, SQL es una parte fundamental (en muchos casos, la mayoría) del código de lógica de negocios. Si intenta separarlo del código que opera en los datos devueltos, es más propenso a desequilibrar la comprensibilidad y la facilidad de mantenimiento del código.

Según lo miro, leer datos, procesar datos, escribir datos, buscar datos ... son operaciones similares, y se mantienen mejor en el mismo lugar.

Si comienza a sentir una duplicación de esfuerzos con las consultas, quizás necesite una vista de base de datos o un objeto que pueda encapsular ese aspecto del acceso a la base de datos.

Otro consejo es tener un buen método de consulta de base de datos. En el software que escribo (PostgreSQL, MySQL, SQL Server), me he asegurado de que la mayor parte de mis operaciones de consulta puedan tener lugar como una sola declaración de código.

GetValue(SQL, [transaction], [array_of_params])
GetRow(SQL, [transaction], [array_of_params])
GetRowList(SQL, [transaction], [array_of_params])
GetValueList(SQL, [transaction], [array_of_params])
Execute(SQL, [transaction], [array_of_params])

Esas son (aproximadamente) las llamadas a funciones principales que aseguro que son parte de mi "objeto de conexión". Depende del idioma, lo que realmente implemente, pero mi punto es mantenerlo realmente, realmente simple y sin dolor.

En resumen, trate a SQL como una parte nativa de la programación y no haga un resumen por el bien de la abstracción.

gahooa
fuente
1
Una gran respuesta. tal vez solo necesito dar un paso atrás y comenzar a mirar el SQL como parte del código, no solo disperso entre él.
jellyfishtree
1
"no abstraer en aras de la abstracción" - Buen punto. Resumen en aras de un código más comprensible.
Jason Baker,
'Otro consejo es tener un buen método de consulta de base de datos': definitivamente estoy de acuerdo. Ayuda mucho cuando solo hay un lugar para modificar el código cuando cambia la lógica de negocios.
Michael K
1
¿Dónde pones el SQL? ¿Se compila en la aplicación y se envía utilizando los métodos anteriores?
Johnny
Según el comentario de OP sobre la respuesta de Jason Baker, "mirando el barril de una consulta SQL gigante ...", ¿cómo aborda esto el problema de leer grandes bloques de texto SQL?
JeffO
0

Generalmente, tener una capa de modelo separada es el mejor enfoque. Hay una serie de patrones de diseño empresarial que dan formas de diseñar esto.

Jason Baker
fuente
lo siento, debería haber sido más específico ... Ya estoy asumiendo que los tienes separados en una capa modelo. Pero una capa modelo todavía puede dispersarse bastante con el código SQL. Tal vez esto es inevitable. La otra cosa que me monstruos en el Código modelo de código que es "construye una consulta SQL", basada en una lógica ... tal vez esto se debe separar hacia fuera en su propia fábrica o algo ...
jellyfishtree
2
@jellyfishtree - Entonces me temo que no entiendo cuál es el problema. Quiero decir, ¿tienes miedo de que tu capa de modelo termine con demasiado código de modelo?
Jason Baker,
Una refutación válida. Me preocupa la legibilidad. Un buen código de modelo generalmente es bastante fácil de entender, pero mirar el barril de una consulta SQL gigante no tiene exactamente su significado. Obviamente, lo primero que debe hacer es comentar adecuadamente esas consultas, pero no es lo mismo que un buen código de autodocumentación y este tipo de secciones se dispersan por todo el modelo. Lo acepto, pero me preguntaba si hay una mejor manera de aislar u organizar las sentencias SQL locos en el modelo ...
jellyfishtree
0

Podría ser una buena idea separar la capa de su modelo en 3 subcapas: "entidades", "repositorios" y "servicios". Esto le dará una separación de preocupaciones y reunirá SQL en un solo lugar, fuera de su lógica empresarial.

En este escenario, todo el código de recuperación de datos, incluido el SQL complejo, se ubicará en repositorios. Por lo tanto, el objetivo del repositorio es ocultar sentencias SQL complejas detrás de métodos autoexplicativos como getUsersWithActiveSubscription().

La entidad extrae los nombres de campo reales de la tabla DB con getters y setters, puede proporcionar alguna conversión de datos entre los tipos de campo DB y los tipos disponibles en su lenguaje de aplicación / programación. Si su ORM lo admite, las entidades pueden manejar asociaciones.

La capa de servicio es el lugar para la lógica empresarial. El servicio recupera entidades utilizando repositorios, actúa sobre ellas y las almacena de nuevo.

GerKirill
fuente