sql - ventajas - orm villano
¿Usando un ORM o SQL simple? (13)
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 creo que la mayoría de los desarrolladores necesitan, cuando intentan encontrar el mejor ORM para sus necesidades:
- codigo de GENERACION
- enlace 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, no pensarías que se están ejecutando contra un RDBMS. Por otro lado, eligió un RDBMS precisamente porque
- Es una fuente de datos robusta.
- SQL puede hacer muchas cosas buenas, de rendimiento (selecciones anidadas, uniones, uniones complejas, etc.). A menudo los ORM no pueden hacer estas cosas.
- usted puede manejar transacciones y sesiones usted mismo
- Tienes UDT y procedimientos almacenados.
jOOQ aborda exactamente estos puntos. Se desempeñará tan bien como JDBC, pero sin el dolor.
Para algunas de las aplicaciones que he desarrollado (y luego procedí a olvidar), 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.
Pensándolo bien, sería mucho mejor usar un contenedor ligero para manejar las inconsistencias de la base de datos en lugar de usar un ORM.
Cualquier diseño respetable necesitará algo de abstracción para la base de datos, solo para manejar el desajuste de impedancia. Pero el primer paso más simple (y adecuado para la mayoría de los casos) que yo esperaría sería un DAL, no un ORM de peso pesado. Tus únicas opciones no son las que están al final del espectro.
EDITAR en respuesta a un comentario que me solicita que describa cómo distingo DAL de ORM:
Un DAL es lo que usted mismo escribe, tal vez a partir de una clase que simplemente encapsula una tabla y asigna sus campos a las propiedades. Un ORM es un código que usted no escribe o mecanismos de abstracción inferidos de otras propiedades de su esquema dbms, principalmente PK y FK. (Aquí es donde se descubre si las abstracciones automáticas comienzan a filtrarse o no. Prefiero informarlas intencionalmente, pero esa puede ser mi preferencia personal).
Digo SQL simple para R eads, ORM para CUD .
El rendimiento es algo que siempre me preocupa, especialmente en aplicaciones web, pero también la capacidad de mantenimiento y legibilidad del código. Para abordar estos problemas escribí SqlBuilder .
El dilema de si usar un marco o no es bastante común en el escenario de desarrollo de software moderno.
Lo que es importante comprender es que cada marco o enfoque tiene sus pros y sus contras: por ejemplo, en nuestra experiencia, encontramos 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 resulta importante evaluar el rendimiento y la eficacia de la herramienta ORM.
También es importante comprender que no es obligatorio seleccionar un marco o un enfoque y poner en práctica todo lo que contiene. Lo que queremos decir con esto es que podemos tener una combinación de ORM y lenguaje de consulta nativo. Muchos marcos ORM otorgan puntos de extensión al complemento en SQL nativo. Debemos tratar de no usar en exceso un marco o un enfoque. Podemos combinar ciertos marcos o enfoques y llegar con una solución adecuada.
Puede utilizar 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.
Hablando como alguien que pasó bastante tiempo trabajando con JPA (Java Persistence API, básicamente la API de ORM estandarizada para Java / J2EE / EJB), que incluye Hibernate, EclipseLink, Toplink, OpenJPA y otros, compartiré algunos de mis observaciones
- Los ORM no son rápidos. Pueden ser adecuados y la mayoría de las veces es correcto, pero en un entorno de alto volumen y baja latencia son un no-no;
- En los lenguajes de programación de propósito general como Java y C #, se necesita una gran cantidad de magia para hacer que funcionen (p. Ej., El tejido de tiempo de carga en Java, instrumentación, etc.);
- Cuando use un ORM, en lugar de alejarse de SQL (lo que parece ser su intención), se sorprenderá de cuánto tiempo pasa modificando XML y / o anotaciones / atributos para que su ORM genere un SQL eficaz;
- 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 formato y cuando tienes que usar SQL en bruto en JPA no es bonito (C # /. Net al menos tiene tipos dinámicos - var - que es mucho mejor que una matriz de objetos);
- Hay un montón de "errores" cuando se utilizan ORMs. Esto incluye un comportamiento no deseado o inesperado, el hecho de que tiene que desarrollar la capacidad de hacer actualizaciones de SQL en su base de datos (mediante el uso de refresh () en JPA o métodos similares porque JPA almacena en caché todo de forma predeterminada para que no detecte una base de datos directa actualización: ejecutar actualizaciones directas de SQL es una actividad de soporte de producción común);
- La discrepancia entre el objeto y la relación 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. En ocasiones sentí que JPA iba demasiado lejos y llegó a una ley real de rendimientos decrecientes en los que la complejidad no estaba justificada por la abstracción.
Hay otro problema que lleva 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 un servicio u otras capas intermedias, pero estos son los 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 de más métodos de SQL sin procesar es que usted termina con todos estos VO (objetos de valor) o DTO (objetos de transferencia de datos) que son utilizados por una sola consulta. Esto se promociona como una ventaja de los ORM porque te deshaces de eso.
El problema es que los problemas no desaparecen con los ORM, simplemente se mueven hacia arriba a la capa de presentación. En lugar de crear VOs / DTOs 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 persistencia en la tecnología de elección (en Java) en estos días es ibatis. Es una envoltura bastante delgada alrededor de SQL que hace un 90% más de lo que puede hacer JPA (incluso puede hacer la carga perezosa de las relaciones, aunque no está bien documentada) pero con mucha 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, habría 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 malo ™. Tal vez sea así (en teoría), pero te diré qué: habría conducido a un código más simple, una pila más simple y más productividad.
La clave que hizo que mi ORM usara realmente era 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 de código. Pero cuando tienes un equipo 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 compilación es algo brillante de observar, especialmente cuando usas CI. Es posible que su código no sea el más rápido, pero su codificación será: sé cuál tomaría en la mayoría de los proyectos.
Mi recomendación es desarrollar un ORM mientras el Esquema aún es fluido, usar el perfilado para encontrar cuellos de botella y luego ajustar las áreas que lo necesitan usando Sql en bruto.
Otra idea es que el almacenamiento en caché integrado en Hibernate a menudo puede realizar mejoras de rendimiento masivas si se usa de la manera correcta. No más volver a la base de datos para leer los datos de referencia.
Los ORM tienen algunas características agradables. Pueden manejar gran parte del trabajo de perro de copiar columnas de bases de datos a campos de objetos. Por lo general, manejan la conversión de los tipos de fecha y hora del idioma al tipo de base de datos apropiado. Por lo general, manejan las relaciones de uno a muchos de manera bastante elegante al instanciar objetos anidados. Descubrí que si diseña su base de datos teniendo en cuenta las fortalezas y debilidades del ORM, ahorra mucho trabajo al ingresar y salir 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 el "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 presenta 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á objetos en caché. visto anteriormente, de lo contrario habría consultado la base de datos varias veces.
Para las aplicaciones que tienen muchos informes, o que tratan con un gran número 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 de memoria inútil. En ese caso, el mapeo simple de SQL (LinQ o iBatis) o las 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).
Me gustaría añadir mi voz al coro de respuestas que dicen "¡Hay un punto medio!".
Para un programador de aplicaciones, SQL es una mezcla de cosas que puede querer controlar y cosas que casi con certeza no desea que se molesten en controlar.
Lo que siempre he querido es una capa (llámela DAL, ORM o micro-ORM, no me importa cuál) que se hará cargo de las decisiones completamente predecibles (cómo deletrear palabras clave SQL, a dónde van los paréntesis, cuando para 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 del SQL, es decir, cómo organizar los JOIN, los cálculos del lado del servidor, DISTINTOS, BYS GRUPOS, subconsultas escalares, etc.
Así que 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 cómo se ve un "término medio".
No hay una solución de "una sola herramienta para todos", y esto también es cierto para la pregunta "¿debo usar un / o m o no? ''.
Yo diría: si tiene que escribir una aplicación / herramienta que se enfoca en "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 escribiera una aplicación empresarial / empresarial que contenga mucha lógica de "dominio", escribiría un modelo de clase rico que expresaría este dominio en código. En tal caso, un mapeador OR / M puede ser muy útil para hacerlo con éxito, ya que le quita un montón de código de plomería.
ORM no es solo portabilidad (lo que es un poco difícil de lograr incluso con ORMs). 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 repetidas (seleccionadas por PK o por predicados, inserciones, actualizaciones y eliminaciones) y le permite concentrarse en el dominio del problema.
Sé que esta pregunta es muy antigua, pero pensé que publicaría una respuesta en caso de que alguien se diera cuenta como yo. Los ORM han recorrido un largo camino. Algunos de ellos realmente le 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 datos de SQL.
Una de las aplicaciones que he desarrollado es un bot IRC escrito en python. Los módulos que utiliza se ejecutan en subprocesos separados, pero no he encontrado una manera de manejar el subproceso cuando se usa sqlite. Sin embargo, eso podría ser mejor para una pregunta separada.
Realmente debería haber reescrito tanto el título como la pregunta real. Nunca antes había usado un DAL en ningún idioma.
Utilice un ORM que funcione como SQL, pero que proporcione controles en tiempo de compilación y seguridad de tipos. Me gusta 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);
}
Completamente en streaming. Fácil de configurar (no hay asignaciones para definir: lee los esquemas existentes). Admite uniones, transacciones, consultas internas, agregación, etc. Casi cualquier cosa que pueda hacer en SQL. Y ha sido probado a partir de conjuntos de datos gigantes (series cronológicas financieras) hasta trivial (Android).