¿ORM es una mala herramienta para estructuras de DB en forma de árbol?

8

Sé que esta pregunta podría cerrarse en función de la opinión, pero lo que necesito en este momento son algunas opiniones respaldadas por argumentos.

Estoy creando una aplicación con Postgres y Ecto (Elixir) como la capa de persistencia. Hay una entidad que hace referencia a sí misma para que pueda construir una estructura en forma de árbol con ella. Cuanto más trato de hacer esto con Ecto, más frustrado me siento.

¿Son los ORM simplemente una mala herramienta para crear estructuras DB complejas con muchas asociaciones? La forma orientada a objetos que ORM intenta imponer sobre los datos relacionales parece ser un mal enfoque aquí. Los objetos están aislados. Si interactúan con otros objetos, (se supone que deben) enviar mensajes. Sus detalles internos deben permanecer ocultos. Los datos relacionales forman un gráfico abierto y transparente. Estos dos mundos parecen ser completamente incompatibles conmigo.

Sin embargo, los ORM son muy comunes y populares. ¿La mayoría de las aplicaciones web funcionan con entidades bastante aisladas que funcionan bien con ORM, o por qué? Me parece que si desea implementar cualquier modelo ERD medio complejo utilizando un marco ORM, debe sacrificar el código conciso o el rendimiento.

Adam Libuša
fuente
1
Cada sistema de base de datos puede tener una implementación ligeramente diferente para admitir un árbol o una estructura de datos "jerárquica". Por ejemplo, Oracle tiene COMENZAR CON y CONECTAR POR y el servidor SQL tiene expresiones de tabla comunes (CTE). Entonces, antes de elegir un ORM, uno debe determinar si tiene el soporte adecuado para este tipo de estructuras de datos. Algunos ofrecen muy buen soporte, mientras que otros pueden no cubrir esos escenarios. Esta pregunta debería reformularse: ¿Ecto admite estructuras de árbol?
Jon Raynor
Dado que mencionó específicamente postgres, admite consultas recursivas para este tipo de cosas (aunque no lo he usado yo mismo)
Izkata
1
Por supuesto, los ORM son una mala herramienta. Ya existe un lenguaje para expresar expresamente consultas en bases de datos: SQL.
Miles Rout
@Miles Rout En la mayoría de los casos cuando usa SQL simple en lugar de un ORM, se repite mucho.
Jimmy T.
@JimmyT. Eso es falso
Miles Rout

Respuestas:

9

Al final del día, un ORM es solo una abstracción que genera sql para usted y asigna los datos a sus objetos. Guardando (tm) un código de 'placa de caldera'.

Por lo tanto, no hay nada que ORM en su conjunto necesariamente sea malo por definición. El problema es que no usa ORM en su conjunto, ¡debe elegir uno específico y usarlo!

Es posible que un ORM individual no haga muy bien una cosa en particular. Los procesos almacenados, sql dinámico, campos calculados, combinaciones complicadas, etc. pueden ser áreas problemáticas.

Un problema más sutil es que a medida que un ORM intenta manejar todos estos escenarios de forma genérica, se hace más grande y más complicado de usar.

Si tiene una aplicación grande o complicada, es probable que en algún momento tenga un problema con el ORM que ha elegido. Por lo tanto, tiene sentido planificar esto con anticipación y asegurarse de ocultar el ORM detrás de un repositorio. De esa manera, puede cambiarlo por una alternativa, o volver a SQL codificado a mano si es necesario.

Ewan
fuente
1
Cabe señalar que, en muchos ORM (al menos cada uno que he usado ), puede escribir y ejecutar SQL sin formato . Por lo tanto, si el ORM no cumple bien alguna restricción, siempre puede recurrir a hacerlo con SQL nativo, al tiempo que reduce las operaciones 'repetitivas' SELECT * FROM some_table WHERE x = whateverque son extremadamente comunes. Las estructuras jerárquicas se manejan bien en algunos ORM, y terriblemente en otros, por lo que este tipo de consideración debe investigarse antes de decidir renunciar a los ORM por completo.
Chris Cirefice
generalmente puede hacer esto, ¡pero no siempre funciona de la manera que desea! Recientemente tuve este problema exacto con nHibernate y mapeo de campo anulable
Ewan
Nunca he usado nHibernate, pero he usado algunos como Rails 'ActiveRecord, OrmLite (Java) y ActiveJdbc (Java). Cada uno de estos manejadores ejecuta SQL sin formato de manera diferente, por ejemplo, ActiveRecord lo hace realmente fácil, y OrmLite lo hace realmente difícil. ActiveRecord ha estado en desarrollo durante años y años, por lo que seguramente tiene algo que ver con eso. Todos estos pequeños matices son parte de las pruebas de viabilidad, pero a veces
echas de
Sí, por eso digo poner un envoltorio alrededor. todavía puedes usar el orm, pero no estás encerrado si te decepciona de alguna manera
Ewan
Ahorro (tm): me reí un poco ante esto.
corsiKa
7

¿Son los ORM simplemente una mala herramienta para crear estructuras DB complejas con muchas asociaciones?

No. Como ejemplo, Ruby on Rails usa ActiveRecord, que maneja las asociaciones. En el ejemplo aquí: /programming/5109893/rails-how-do-self-referential-has-many-models-work , la estructura en forma de árbol se logra con 2 líneas de código.

Por lo tanto, diría que es muuuucho más fácil que intentar rodar sus propias consultas sql.

¿La mayoría de las aplicaciones web funcionan con entidades bastante aisladas que funcionan bien con ORM, o por qué?

Probablemente no, pero eso son solo conjeturas. Los ORM existen en un ecosistema donde prosperan, lo que sugiere que se están utilizando. He usado ORM para sistemas con más de 20 modelos asociados y me pareció que estaban bien. Nunca forcé a los objetos a aislarse con solo pasar mensajes.

Como opinión resumida, si está creando modelos ERD "complejos", no existe una herramienta que los facilite. Solo herramientas que los hacen funcionar.

cmonkey
fuente
Sí, utilicé Entity Framework para un proyecto que tenía CustomerId (PK) y ParentCustomerId (FK anulable que apunta de nuevo a la tabla de clientes) para crear n niveles de árboles de jerarquía de clientes. No tuve ningún problema aquí (aunque muchas comprobaciones nulas / .Any()declaraciones LINQ)
USER_8675309
Hibernate (Java) es otro buen ejemplo de un ORM que puede manejar árboles sin problemas, lo que requiere prácticamente cero esfuerzo adicional . La complejidad de la consulta está oculta para el cliente. Los padres y los niños pueden ser perezosos. El ID del objeto principal es solo otra columna en la base de datos. Una lista ordenada de nodos secundarios también se puede admitir de forma transparente con la adición de una columna que contiene un índice de lista. (Sin ordenar vs consideraciones de recogida de pedidos no son exclusivos de los árboles aquí.)
Jason C
No puedo evitar sentir que esta es una respuesta engañosa. Debido a que un ORM maneja este caso, no significa que los ORM en general puedan manejarlo. De hecho, un rápido google muestra que el registro activo TIENE errores y errores en algunas versiones sobre auto-referencia github.com/rails-api/active_model_serializers/issues/211 y coderwall.com/p/4d2utg/…
Ewan
@Ewan: estoy dispuesto a reformular mi respuesta, pero creo que responde adecuadamente la pregunta de si los ORM en general son malos. Es una pregunta diferente preguntar si todos los ORM pueden manejar este caso, o si son la mejor solución. La existencia de una herramienta ORM menos adecuada o un error en una versión no cambia la generalización. También sé que también tuve errores en mi SQL.
cmonkey
5

Como se señaló en al menos otra respuesta aquí, todos los ORM no son lo mismo. Algunos ORM hacen suposiciones muy significativas sobre cómo debe estructurarse la base de datos. Las herramientas deberían proporcionar algún soporte para salir de este modelo, pero cuanto más salgas de ese modelo, menos valor tendrá el ORM. Si está trabajando con una herramienta ORM más dominante, tendrá una experiencia mucho mejor si diseña la base de datos según sus supuestos implícitos.

Nunca he entendido realmente por qué muchos desarrolladores y arquitectos consideran que los ORM son esenciales. Esto puede deberse al hecho de que casi nunca he tenido una base de datos de campo verde con la que trabajar y el tiempo y el esfuerzo necesarios para realizar la asignación de ORM fue mucho más trabajo que escribir el SQL. O el mapeo era simple (y también lo era el SQL) o era complicado y necesitaba SQL (o algo similar) de todos modos. El "soporte" transaccional incluido en ORM ha sido más una fuente de errores y problemas que una ayuda, en mi experiencia.

Su kilometraje puede variar, pero he llegado a creer que es mejor pensar en la persistencia de la base de datos como un caso especial de serialización de datos. Y así como creo que no tiene sentido creer que se puede 'enviar' un objeto a través del cable, no creo que tenga sentido pensar en escribir objetos en una base de datos. Incluso creo que es completamente válido tener múltiples representaciones de objetos de los mismos datos para diferentes necesidades. Asignar objetos a tablas y viceversa se ha convertido en un fin en sí mismo en lugar de una solución a un problema. No estoy convencido de que la mayoría de las personas que usan estas herramientas tengan una razón clara para querer hacerlo. Se ha convertido en un defecto.

JimmyJames
fuente
1
los totalizadores están de acuerdo, una vez que te resignas a escribir el sql y al mapeo, rara vez lleva más tiempo a largo plazo y tienes el control total
Ewan
@Ewan Para ser justos, creo que se necesita un poco de experiencia para saber cómo construir las abstracciones adecuadas entre la lógica y el DB. Los ORM pueden ayudar a los desarrolladores a llegar a algo viable rápidamente. Es la idea de que los objetos se pueden traducir a tablas y viceversa, que es donde creo que hay problemas. Es cierto para un subconjunto de modelos de datos y modelos de objetos, pero no en general.
JimmyJames
1
@JimmyJames Es cierto si todo lo que necesita son operaciones CRUD muy simples por tabla Más allá de eso, un ORM no micro es una maldición. (Y personalmente considero que la idea de crear un objeto para cada conjunto diferente de columnas que regresa para un micro-ORM es molesto, aunque puede ser la menor de las cosas molestas en un lenguaje estáticamente mecanografiado).
jpmc26
1
@ jpmc26 Quiero dejar de lado el atolladero estático frente al dinámico, pero creo que está destacando el tipo de cosas de las que estoy hablando. Si todo lo que quiero hacer es extraer algunos datos, transformarlos mínimamente y devolverlos como JSON, por ejemplo, realmente no necesito asignar mapas a objetos para lograr esto. El objeto no tiene funcionalidad real. Actúa como un mapa donde los datos se almacenan momentáneamente. Pero he visto ORM utilizados para resolver ese tipo de problema. A menudo, la respuesta es generar las clases para esos objetos, pero creo que eso resalta lo innecesarios que son.
JimmyJames
De alguna manera, omití lo que originalmente pretendía decir: la situación no es mejor con una nueva base de datos que está desarrollando. Solo depende del tipo de consultas que necesita escribir. Para CRUD por tabla muy simple, puede ahorrar un poco de tiempo. Pero si tiene consultas que mezclan y combinan datos de diferentes tablas o consultas que son complejas (agrupación compleja, CTE, subconsultas), cualquier cosa que no sea micro es automáticamente mucho más problema de lo que vale. Incluso si puede escapar con CRUD muy simple al principio, está apostando a que el éxito no conducirá a una mayor complejidad.
jpmc26