¿Usando un ORM o SQL simple? [cerrado]

245

Para algunas de las aplicaciones que desarrollé (luego olvidé), he estado escribiendo SQL simple, principalmente para MySQL. Aunque he usado ORM en python como SQLAlchemy , no me quedé con ellos por mucho tiempo. Por lo general, era la documentación o la complejidad (desde mi punto de vista) lo que me frenaba.

Lo veo así: use un ORM para la portabilidad, SQL simple si solo va a usar un tipo de base de datos. Realmente estoy buscando consejos sobre cuándo usar un ORM o SQL al desarrollar una aplicación que necesita soporte de base de datos.

Pensando en ello, sería mucho mejor usar un contenedor ligero para manejar las inconsistencias de la base de datos en lugar de usar un ORM.

Hydrapheetz
fuente
Estandarización, seguridad, mantenibilidad, abstracción del lenguaje, DRY, etc.
Ben
El rendimiento con ORM puede estar cerca de SQL, depende de si lo usa correctamente y con la configuración correcta ... Vea cómo hacer EF6.x 5x más rápido: linkedin.com/pulse/…
baHI
Para la arquitectura ORM y cómo hacerlo (qué evitar), aquí está mi otro enlace: linkedin.com/pulse/…
baHI
El mapeo relacional de objetos (ORM) ya es muy popular en muchos lenguajes de programación y es una de las mejores alternativas para SQL. Me inspiré en el estilo de encadenamiento de métodos para crear CQL para mi proyecto TRIADB. healis.eu/triadb/#latest-release
Athanassios
2
Es tonto que esta pregunta se haya cerrado.
Mitch Wheat

Respuestas:

169

Los ORM tienen algunas características agradables. Pueden manejar gran parte del trabajo de copiar columnas de bases de datos a campos de objetos. Generalmente manejan la conversión de los tipos de fecha y hora del idioma al tipo de base de datos apropiado. En general, manejan las relaciones de uno a muchos de manera muy elegante también al instanciar objetos anidados. Descubrí que si diseña su base de datos teniendo en cuenta las fortalezas y debilidades del ORM, se ahorra mucho trabajo al introducir y sacar datos de la base de datos. (Querrá saber cómo maneja el polimorfismo y las relaciones de muchos a muchos si necesita mapearlos. Son estos dos dominios los que proporcionan la mayor parte del 'desajuste de impedancia' que hace que algunos llamen a ORM la 'vietnam de la informática' .)

Para las aplicaciones que son transaccionales, es decir, usted realiza una solicitud, obtiene algunos objetos, los atraviesa para obtener algunos datos y los muestra en una página web, el impuesto sobre el rendimiento es pequeño y, en muchos casos, ORM puede ser más rápido porque almacenará en caché los objetos. visto antes, de lo contrario habría consultado la base de datos varias veces.

Para las aplicaciones que generan muchos informes o que manejan una gran cantidad de filas de bases de datos por solicitud, el impuesto ORM es mucho más pesado y el almacenamiento en caché que hacen se convierte en una gran carga inútil de acaparamiento de memoria. En ese caso, el mapeo SQL simple (LinQ o iBatis) o consultas SQL codificadas a mano en un DAL delgado es el camino a seguir.

He encontrado que para cualquier aplicación a gran escala te encontrarás usando ambos enfoques. (ORM para CRUD directo y SQL / thin DAL para informes).

Cameron Pope
fuente
¿Podría definir 'gran número de filas de base de datos por solicitud'? Por favor :)
Mosselman
Entonces, ¿puedo integrar JPA con IBatis, por ejemplo? ¿Y hacer que funcionen en la misma transacción?
Jaime Hablutzel
2
Otra consideración que nadie parece discutir es la gestión básica del estado. Toda esta pila de marcos (JSF, JPA, etc.) se basa en métodos get / set de beans Java. Esta es una TONELADA de repetitivo para cada tabla, para cada columna y ... aquí está el antipatrón real: solo para exponer cada campo como si fuera público. En efecto, tener un método get / set en los campos de un objeto / tabla / fila está muy cerca de violar cada inquilino de información oculta y encapsulada. Por último, volviendo a la gestión estatal ... ¿dónde está la opción de inmutabilidad? ¿Pueden o deben permitirse los objetos de medio juego? No hay opción con la mayoría.
Darrell Teague el
2
Me gustaría afinar y particularmente acordar una declaración clave en esta respuesta. "Para las aplicaciones que manejan una gran cantidad de filas de bases de datos por solicitud, el impuesto ORM es mucho más pesado". ORM es bueno solo para desarrolladores y mantenimiento porque la mayoría de los desarrolladores no son muy buenos en SQL, pero si realmente estás hablando de rendimiento, SQL lo supera por completo.
Manachi
"la mayoría de los desarrolladores no son muy buenos en SQL" ??? Diría que la mayoría de los desarrolladores no saben cómo usar LINQ, el poder de los árboles de expresión y los ORM en general, la generación de código y muchas otras cosas. Pero no, no tengo ninguna base para hacer una declaración tan fuerte.
Adanay Martín
253

Hablando como alguien que pasó bastante tiempo trabajando con JPA (Java Persistence API, básicamente la API ORM estandarizada para Java / J2EE / EJB), que incluye Hibernate, EclipseLink, Toplink, OpenJPA y otros, compartiré algunos de mis observaciones

  1. Los ORM no son rápidos. Pueden ser adecuados y la mayoría de las veces es adecuado, pero en un entorno de alto volumen y baja latencia son un no-no;
  2. En lenguajes de programación de propósito general como Java y C #, necesita mucha magia para que funcionen (por ejemplo, tejido de carga en Java, instrumentación, etc.);
  3. Cuando utilice un ORM, en lugar de alejarse de SQL (que parece ser la intención), se sorprenderá de la cantidad de tiempo que pasa ajustando XML y / o anotaciones / atributos para que su ORM genere SQL con rendimiento;
  4. Para consultas complejas, realmente no hay sustituto. Al igual que en JPA, hay algunas consultas que simplemente no son posibles que están en SQL sin procesar y cuando tienes que usar SQL sin procesar en JPA no es bonito (C # /. Net al menos tiene tipos dinámicos, var, que es mucho mejor que una matriz de objetos);
  5. Hay muchas "trampas" cuando se usan ORM. Esto incluye un comportamiento involuntario o inesperado, el hecho de que tiene que construir la capacidad de realizar actualizaciones SQL en su base de datos (mediante el uso de refresh () en JPA o métodos similares porque JPA almacena en caché todo de manera predeterminada para que no capture una base de datos directa actualización: ejecutar actualizaciones directas de SQL es una actividad de soporte de producción común);
  6. El desajuste relacional de objetos siempre va a causar problemas. Con cualquier problema de este tipo, existe una compensación entre la complejidad y la integridad de la abstracción. A veces sentí que JPA fue demasiado lejos y alcanzó una ley real de rendimientos decrecientes donde la complejidad no estaba justificada por la abstracción.

Hay otro problema que requiere un poco más de explicación.

El modelo tradicional para una aplicación web es tener una capa de persistencia y una capa de presentación (posiblemente con servicios u otras capas intermedias, pero estas son las dos importantes para esta discusión). Los ORM fuerzan una vista rígida desde su capa de persistencia hasta la capa de presentación (es decir, sus entidades).

Una de las críticas a los métodos SQL más crudos es que terminas con todos estos VO (objetos de valor) o DTO (objetos de transferencia de datos) que se usan simplemente con una consulta. Esto se promociona como una ventaja de los ORM porque se deshace de eso.

La cuestión es que esos problemas no desaparecen con los ORM, simplemente se mueven hacia la capa de presentación. En lugar de crear VO / DTO para consultas, crea objetos de presentación personalizados, generalmente uno para cada vista. ¿Cómo es esto mejor? En mi humilde opinión no lo es.

He escrito sobre esto en ORM o SQL: ¿ Ya llegamos? .

Mi tecnología de persistencia de elección (en Java) en estos días es ibatis. Es un envoltorio bastante delgado alrededor de SQL que hace más del 90% de lo que JPA puede hacer (incluso puede hacer una carga diferida de las relaciones, aunque no está bien documentado) pero con mucho menos sobrecarga (en términos de complejidad y código real).

Esto surgió el año pasado en una aplicación GWT que estaba escribiendo. Mucha traducción de EclipseLink a objetos de presentación en la implementación del servicio. Si estuviéramos usando ibatis hubiera sido mucho más sencillo crear los objetos apropiados con ibatis y luego pasarlos de arriba a abajo de la pila. Algunos puristas podrían argumentar que esto es Bad ™. Tal vez sea así (en teoría), pero te digo qué: habría llevado a un código más simple, una pila más simple y más productividad.

cletus
fuente
2
Me inspiró publicar otra pregunta (aunque wiki comunitaria) solo para recopilar recursos sobre cosas como esta. En cuanto al último párrafo: me gusta la simplicidad. Probablemente demasiado.
hydrapheetz
3
iBATIS es genial, pero quizás quieras probar jOOQ: jooq.sourceforge.net . Su enfoque principal es precisamente permanecer cerca de SQL por las 6 razones que mencionó.
Lukas Eder
55
+1 para el punto 3. Muchos sienten que usar ORM lo alivia de tener un conocimiento profundo de SQL. La cosa es que una vez que pueda / aprenda a hacer gimnasia con SQL, probablemente se encontrará alejándose de ORM ... muy rápidamente.
Ryan Fernandes
44
Entonces, ahora es el final de 2013 y, como todos sabemos, nada podría ser más engañoso que los "hechos antiguos". ¿Puedo preguntarle si sus puntos siguen siendo los mismos? Si no, sería genial si pudieras escribir una entrada de blog / actualizar tu respuesta en consecuencia.
Dominik
3
var no produce un tipo dinámico en .NET, las variables con la palabra clave dinámica son tipos dinámicos en .NET. var sigue siendo mecanografía estática. Ver stackoverflow.com/questions/961581/…
Fazi
45

Digo SQL simple para R eads, ORM para CUD .

El rendimiento es algo que siempre me preocupa, especialmente en las aplicaciones web, pero también el mantenimiento y la legibilidad del código. Para abordar estos problemas, escribí SqlBuilder .

Max Toro
fuente
1
¿Qué es el CUD? No puedo encontrar la definición.
Kimchi Man
27
@KimchiMan CRUD sin la R.
Max Toro
3
CUD: crear, actualizar, eliminar.
Combine el
14

ORM no es solo portabilidad (que es un poco difícil de lograr incluso con ORM, para el caso). Lo que le proporciona es básicamente una capa de abstracción sobre un almacén persistente, cuando una herramienta ORM lo libera de escribir consultas SQL repetitivas (selecciona por PK o por predicados, inserciones, actualizaciones y eliminaciones) y le permite concentrarse en el dominio del problema.

Anton Gogolev
fuente
3
Estaba pensando en algo más cercano a la portabilidad en todos los sabores de bases de datos. No debería publicar preguntas a altas horas de la noche.
hydrapheetz
1
Eso es exactamente lo que estaba diciendo: incluso los escenarios más básicos pueden estar sujetos a errores en diferentes DBMS, por ejemplo, diferentes manejos de NULL.
Anton Gogolev el
Un ORM le brinda una capa de abstracción sobre las relaciones entre los objetos, pero no hay una gran ventaja con respecto a las consultas repetitivas que menciona. En una aplicación JDBC, puede escribir ese tipo de consultas con una pequeña cantidad de código en una superclase abstracta o clase de utilidad. No es necesario repetir el repetitivo para cada nueva tabla.
Kevin Stembridge
11

Cualquier diseño respetable necesitará algo de abstracción para la base de datos, solo para manejar la falta de coincidencia de impedancia. Pero el primer paso más simple (y adecuado para la mayoría de los casos) que esperaría sería un DAL, no un ORM de peso pesado. Sus únicas opciones no son aquellas en los extremos del espectro.


EDITAR en respuesta a un comentario que me solicita que describa cómo distingo DAL de ORM:

Un DAL es lo que escribe usted mismo, tal vez a partir de una clase que simplemente encapsula una tabla y asigna sus campos a propiedades. Un ORM es código que no escribe o mecanismos de abstracción inferidos de otras propiedades de su esquema dbms, principalmente PK y FK. (Aquí es donde puede averiguar si las abstracciones automáticas comienzan a filtrarse o no. Prefiero informarlas intencionalmente, pero esa puede ser mi preferencia personal).

dkretz
fuente
2
¿Dónde trazas la línea entre lo que es un DAL y lo que es un ORM?
caos
44
Entonces, si usted es el autor de un ORM, ¿su ORM se convierte automáticamente en un DAL? :)
Bombe
DAL = capa de persistencia y ORM es una herramienta que utiliza dentro de su DAL para realizar operaciones CRUD en el almacén de datos.
Vahid Ghadiri
7

Cada herramienta tiene su propósito y visión. He creado http://www.jooq.org/ exactamente para satisfacer sus necesidades, aunque iBatis es probablemente una buena solución para usted también.

jOOQ tiene características básicas de ORM, pero se centra principalmente en las cosas que supongo que la mayoría de los desarrolladores necesitan más, cuando intentan encontrar el mejor ORM para sus necesidades:

  • codigo de GENERACION
  • unión variable (eso es un dolor en JDBC)
  • Abstracción de sintaxis SQL (para evitar errores de sintaxis)

Pero a menudo van demasiado lejos y proporcionan tanta abstracción que no pensarías que se están ejecutando contra un RDBMS. Por otro lado, elegiste un RDBMS precisamente porque

  • es una fuente de datos robusta
  • SQL puede hacer muchas cosas buenas y eficaces (selecciones anidadas, uniones, combinaciones complejas, etc.). A menudo, los ORM no pueden hacer estas cosas.
  • puede manejar transacciones y sesiones usted mismo
  • tiene UDT y procedimientos almacenados

jOOQ aborda exactamente estos puntos. Funcionará tan bien como JDBC, pero sin el dolor.

Lukas Eder
fuente
6

El dilema de si usar un marco o no es bastante común en el escenario de desarrollo de software moderno.

Lo importante es comprender que cada marco o enfoque tiene sus pros y sus contras, por ejemplo, en nuestra experiencia, hemos encontrado que ORM es útil cuando se trata de transacciones, es decir, operaciones de inserción / actualización / eliminación, pero cuando se trata de obtener datos con complejos resultados se vuelve importante evaluar el rendimiento y la efectividad de la herramienta ORM.

También es importante comprender que no es obligatorio seleccionar un marco o un enfoque e implementar todo en eso. Lo que queremos decir con eso es que podemos tener una combinación de ORM y lenguaje de consulta nativo. Muchos marcos ORM dan puntos de extensión al complemento en SQL nativo. Deberíamos tratar de no usar demasiado un marco o un enfoque. Podemos combinar ciertos marcos o enfoques y llegar con una solución adecuada.

Puede usar ORM cuando se trata de inserción, actualización, eliminación, control de versiones con alto nivel de concurrencia y puede usar SQL nativo para la generación de informes y listas largas

Rutesh Makhijani
fuente
3
¿Por qué un ORM es mejor para una alta concurrencia?
user359996
6

La clave que hizo que mi uso de ORM realmente volara fue la generación de código. Estoy de acuerdo en que la ruta ORM no es la más rápida, en términos de rendimiento del código. Pero cuando tiene un equipo de mediano a grande, la base de datos está cambiando rápidamente, la capacidad de regenerar clases y asignaciones de la base de datos como parte del proceso de construcción es algo brillante para la vista, especialmente cuando usa CI. Por lo tanto, es posible que su código no sea el más rápido, pero su codificación lo será: sé cuál tomaría en la mayoría de los proyectos.

Mi recomendación es desarrollar usando un ORM mientras el Schema todavía es fluido, usar perfiles para encontrar cuellos de botella, luego ajustar las áreas que lo necesitan usando Sql sin procesar.

Otro pensamiento, el almacenamiento en caché integrado en Hibernate a menudo puede mejorar enormemente el rendimiento si se usa de la manera correcta. No más volver a la base de datos para leer los datos de referencia.

MrTelly
fuente
2
Absolutamente una cuestión de gusto personal. Para mí, la generación de código es un defecto.
dkretz
55
Lea el segundo párrafo ... tal vez la completitud también sea útil
MrTelly
La generación de código es la única forma de realizar ciertas tareas más rápido. Como todas las herramientas, puede ser potente o provocar un desastre. Técnicamente todos los idiomas están produciendo otros tipos de código.
Banjocat
4

No existe una solución 'una herramienta para todos', y esto también es cierto para la pregunta '¿debería usar un / m o no? '.

Yo diría: si tiene que escribir una aplicación / herramienta que esté muy centrada en los 'datos', sin mucha otra lógica, entonces usaría SQL simple, ya que SQL es el lenguaje específico del dominio para este tipo de aplicaciones.

Por otro lado, si tuviera que escribir una aplicación comercial / empresarial que contenga mucha lógica de 'dominio', entonces escribiría un modelo de clase rico que podría expresar este dominio en código. En tal caso, un mapeador OR / M puede ser muy útil para hacerlo con éxito, ya que le quita mucho código de plomería.

Frederik Gheysels
fuente
"No hay una solución 'una herramienta para todos' ... bueno, debería haberla.
Rushino
1

Una de las aplicaciones que he desarrollado fue un bot IRC escrito en python. Los módulos que usa se ejecutan en subprocesos separados, pero no he descubierto una manera de manejar los subprocesos cuando uso sqlite. Sin embargo, eso podría ser mejor para una pregunta por separado.

Realmente debería haber reformulado tanto el título como la pregunta real. Nunca he usado un DAL antes, en ningún idioma.

Hydrapheetz
fuente
44
Bueno, soy de la opinión de que deberías. SQL sin formato en todo el lugar es bastante abominable.
caos
Bueno sí. Hay un software de foro que pirateo de vez en cuando que tiene toneladas de mysql_query () y mysql_result () por todas partes. Es una locura.
hydrapheetz
¿De qué habla esta "aplicación"?
Zoran Pavlovic
¡Es curioso que esta pregunta se haya hecho a través de una aplicación irc bot y se haya convertido en lo que era (una guía muy útil)! Una aplicación irc bot está en un extremo de la escala, y una aplicación que tiene más de 50-100 tablas con combinaciones complejas y millones de filas de datos con más de 20 desarrolladores trabajando en ella está en el otro extremo de la escala. Me atrevo a decir que cuando se trata del final de la escala de una 'aplicación irc bot', apenas importa.
Manachi
1

Utilice un ORM que funciona como SQL, pero proporciona comprobaciones en tiempo de compilación y seguridad de tipos. Como mi favorito: Data Knowledge Objects (divulgación: lo escribí)

Por ejemplo:

for (Bug bug : Bug.ALL.limit(100)) {
  int id = bug.getId();
  String title = bug.getTitle();
  System.out.println(id +" "+ title);
}

Transmisión completa Fácil de configurar (no hay asignaciones para definir, lee sus esquemas existentes). Admite combinaciones, transacciones, consultas internas, agregación, etc. Prácticamente todo lo que puede hacer en SQL. Y ha sido probado desde conjuntos de datos gigantes (series de tiempo financieras) hasta triviales (Android).

Keredson
fuente
Su IDE también puede proporcionar tales comprobaciones estáticas directamente (IDEA conoce la estructura de la base de datos siempre que le diga dónde está la base de datos / dónde están los archivos DDL, por lo que puede hacer verificaciones de tipo / verificaciones de relación / etc.en sus consultas / procedimientos SQL / lo que sea )
Xenos
Eso es útil. ¿Puede hacerlo como parte de un paso de compilación / CI? ¿Cómo clasifica sql frente a otras cadenas? ¿puede manejar la manipulación de cadenas o solo las constantes de cadenas?
keredson
AbBlock me bloqueará, pero IntelliJ analiza SQL como cualquier otro idioma jetbrains.com/datagrip/features para poder integrarlo en CI / CD / build (¿quizás pidiéndole al equipo de IJ que aísle el código de análisis SQL? tiene tal analizador). El análisis trae el tipo de datos para que pueda agregar controles en ellos (lo he hecho con un complemento personalizado), o controles como "¿las columnas JOIN tienen un índice FK?" etc. Estas serían mejoras claras a las inspecciones SQL nativas de IJ
Xenos
1

Sé que esta pregunta es muy antigua, pero pensé que publicaría una respuesta en caso de que alguien la encontrara como yo. Los ORM han recorrido un largo camino. Algunos de ellos te ofrecen lo mejor de ambos mundos: hacer que el desarrollo sea más productivo y mantener el rendimiento.

Eche un vistazo a los datos SQL ( http://sqldata.codeplex.com ). Es un ORM muy ligero para c # que cubre todas las bases.

Para su información, soy el autor de los datos SQL.

tjscience
fuente
1

Me gustaría agregar mi voz al coro de respuestas que dicen "¡Hay un término medio!".

Para un programador de aplicaciones, SQL es una mezcla de cosas que es posible que desee controlar y cosas que seguramente no desea que se moleste en controlar.

Lo que siempre he querido es una capa (llámela DAL, ORM o micro-ORM, no me importa cuál) que se encargará de las decisiones completamente predecibles (cómo deletrear palabras clave SQL, dónde van los paréntesis, cuándo inventar alias de columna, qué columnas crear para una clase que contiene dos flotantes y un int ...), mientras me deja a cargo de los aspectos de nivel superior de SQL, es decir, cómo organizar JOINs, cálculos del lado del servidor, DISTINCIONES, BY GRUPALES, subconsultas escalares, etc.

Entonces escribí algo que hace esto: http://quince-lib.com/

Es para C ++: no sé si ese es el lenguaje que está utilizando, pero de todos modos podría ser interesante ver esta versión de cómo podría ser un "término medio".

slyqualin
fuente