Hago un alto con la serie de posts sobre la estructuración de los equipos para hacer una introducción a un tema candente, las bases de datos no relacionales y el movimiento noSQL.
Algunos pensarán que esto del noSQL es una moda más, pero lo curioso es que se enfrenta a otra moda mucho más poderosa e influyente, el SQL y las base de datos relacionales. En muchos sitios me enerva una práctica muy común que consiste en que al diseñar la aplicación y analizar los requisitos lo primero que se hace es… ¡el modelo de tablas relacional! Muchos consideran que la aplicación está casi hecha en cuanto tenemos un esquema de base de datos y unas sentencias SQL, y acoplan todo su código a esto. Esta forma de diseñar aplicaciones está muy bien cuando trabajas con COBOL pero desperdicia por completo las características de cualquier lenguaje de programación OO moderno. La cosa llega a tal extremo que muchas personas sólo piensan en aplicaciones CRUD y de hecho hay frameworks como Grails o Rails que te proporcionan una aplicación CRUD muy rápidamente si no te importa acoplarte con la BBDD.
Mi filosofía es un poco diferente, usar Acceptance TDD y DDD y DSL (a.k.a. API Sexy) para definir un core de negocio orientado a objetos que sea fácil de probar, fácil de usar y modele el dominio de la aplicación. Es decir, como uso OO, lo que hago es realmente modelar el negocio mediante un modelo de objetos, que refleja la realidad del problema que queremos resolver y contiene la lógica de negocio. Sobre este modelo monto un DSL para poder trabajar con el modelo escribiendo código que parezca lenguaje natural o al menos sea legible por el analista funcional. En esta filosofía de trabajo la interfaz de usuario y la capa de persistencia son periféricas a este core de negocio. De hecho se puede diseñar el sistema para que tenga distintas interfaces de usuario y puedas cambiar el mecanismo de persistencia de forma sencilla.
Desde este punto de vista, si yo diseño mi sistema con un core OO de negocio robusto, y necesito almacenar los objetos de forma persistente, entonces debo usar una capa de persistencia, y no me importa especialmente cual sea mientras cumpla mis requisitos de la forma más sencilla posible. Desde este punto de vista analicemos lo que nos ofrece una base de datos relacional:
- Persistencia. Ok, es lo que busco.
- Lógica de negocio, en forma de procedimientos almacenados y triggers. Pues no, esto me sobra, lo tengo en el core de negocio.
- Transacciones ACID. Esto depende, si estoy haciendo operaciones críticas que deben realizarse de forma instantánea desde el punto de vista de negocio entonces sí. Si estoy escribiendo una aplicación de redes sociales y quiero escribir una actualización de estado, no me importa mucho si falla al grabarse, o tengo lecturas fantasma. Otro ejemplo de operación no ACID es el de una transferencia monetaria bancaria. Ciertamente das de alta la transferencia de dinero de forma atómica, pero la consolidación de los balances entre la cuenta destino y origen puede tardar días, teniendo mientras tanto un estado “inconsistente”.
- SQL. Un lenguaje de query complejo, que me permite hacer casi cualquier consulta y que para optimizarlo tengo que ser un experto en BBDD. No gracias, las consultas complejas las hago en mi core de negocio, en mi lenguaje de programación favorito, y por que no, con mi DSL. Yo sólo quiero grabar, leer, y hacer unas cuantas consultas muy concretas, no cualquiera. Además, ¿cómo puede una BBDD ser más óptima en la ejecución de la consulta que mi código, hecho específicamente para mi problema? Es el típico caso de que una solución genérica a un problema no puede ser más eficiente que una solución específica para un problema específico. En este caso SQL es un lenguaje de query genérico, y no conoce los detalles específicos y posibles optimizaciones de mi aplicación, sólo puede usar técnicas generales.
- Esquema. Estructura rígida y tipada de almacenamiento en forma de tablas con columnas ¿Para que quiero eso, si la estructura y el modelo y los tipos y validaciones del sistema está en el core OO? Realmente esto es un dolor, todos habréis sufrido con problemas de conversión de tipos entre columnas de tablas y campos de objetos, o entre objetos y tablas. Tal es el problema que nuestra aplicación termina haciendo uso de algún framework de mapeo objeto relacional, como Hibernate o iBatis o JPA, que añade otro grado de complejidad y configuración innecesario. Es innecesario porque la estructura de la información ya está en el modelo de objetos, no es necesaria replicarla en la capa de persistencia.
Si somos prácticos y aplicamos el principio KISS, vemos que una BBDD relacional puede ser, en muchos casos, algo que nos añade una complejidad innecesaria. Nos añade funcionalidades duplicadas con el core OO o simplemente innecesarias en algunos casos. Lo que ocurre es que el típico escenario de aplicación, el típico caso de uso, está cambiando respecto a lo que era antes. Cada vez tenemos más aplicaciones que tienen alguna o todas de las siguientes características:
- Deben soportar grandes volúmenes de datos. Pensad en cualquier red social o en aplicaciones de Google, como el google maps.
- Deben soportar altas cargas de transacciones online, debido a que el número de usuarios en la web puede ser enorme. De hecho cuantos más usuarios tengamos, los señores de negocio estarán más contentos.
- El rendimiento no debe degradarse debido a los dos puntos anteriores.
- ¡Que no se caiga! Hoy en día la caída e indisponibilidad de una aplicación tiene consecuencias monetarias muy fuertes.
- En aplicaciones como las redes sociales, la consistencia no es crítica, con lo que las transacciones ACID no son necesarias.
- ¡Fácil de usar! No quiero sufrir para simplemente grabar datos y hacer cuatro consultas básicas. No quiero saber nada de configuraciones de Hibernate o explains de Oracle.
- ¡Fácil de integrar con un core OO de negocio!
Como vemos en muchos tipos de aplicaciones, las bases de datos relacionales te ofrecen capacidades que no te interesan a cambio de complicarte la vida. Por otro lado puedes tener muchos problemas con los requisitos de rendimiento, escalabilidad y disponibilidad. Para solucionar esos problemas vas a necesitar expertos, máquinas y productos normalmente caros. Lo peor que es que dichos expertos pueden coger una posición de poder y empezar a imponer sus reglas. Lo ideal es que las reglas las ponga el cliente, no un grupo de sacerdotes de una oscura tecnología.
Hasta ahora por tradición y por moda (o por imposición) cada vez que se nos planteaba la necesidad de persistir información elegíamos una BBDD relacional de forma automática y sin pensar. Como la integración entre un core OO y la BBDD relacionales es complicada, la gente llegó a varias soluciones (no necesariamente excluyentes):
- No usar un core OO de negocio. Me hago una aplicación igual que la que hacía en COBOL pero traducida literalmente a JAVA.
- Uso un Grails o un Rails, me acoplo al esquema de la BBDD y ya está.
- Uso mi framework de mapeo objeto relacional (Hibernate, iBatis, etc), e invierto esfuerzo en configurarlo y optimizarlo.
Esto es un razonamiento torticero, como tengo que usar BBDD relacionales entonces me complico la vida o paso de la OO. Es decir, me creo problemas “artificiales”, que no existían originalmente, porque elijo no solucionar el problema original (la persistencia) de forma óptima, sino hacer según manda la tradición y la moda. Lo lógico es analizar que tiene que hacer tu sistema de persistencia y después decidir qué usas. Puedes terminar usando una BBDD relacional si realmente la necesitas, pero en la mayoría de los casos os daréis cuenta que no os hace falta. Este es precisamente el punto de partida del movimiento noSQL.
Resumiendo, el movimiento noSQL, entre otras cosas, te propone:
- No tienes porque usar una BBDD relacional, tienes alternativas para la persistencia de tu modelo de objetos.
- No te hace falta un lenguaje de triggers ni de consultas complejas ya que la lógica de negocio está en la aplicación, no en el sistema de persistencia.
- No necesitas un esquema rígido en tu sistema de persistencia, ya tienes tu modelo de objetos. Puede que incluso trabajes con un lenguaje de programación de tipado dinámico (js, ruby, etc). Simplemente quieres persistir objetos enteros o documentos. La estructura exacta de lo que guardes no debe ser de la incumbencia del sistema de persistencia, sino de tu modelo de negocio.
- Te vale una API sencilla y un modelo de consulta sencillo. Uno muy popular es el clave valor, o tabla hash persistente. Guardas objetos o documentos y los asocias a una clave para poder recuperarlos.
- Puedes prescindir de ACID para conseguir alta disponibilidad, escalabilidad y bajos tiempos de respuesta.
- No odies SQL, simplemente debes saber cuando usarlo y cuando no. Hay casos en los que es la mejor solución, pero no en todos, y creo que cada vez en menos.
En siguientes posts hablaré sobre que sistemas de persistencia noSQL son más usados, su paradigma de desarrollo y como podemos eliminar, en muchos casos, la necesidad de transacciones ACID y el 2PC, con el objetivo de aumentar la disponibilidad y escalabilidad. Iré mezclando posts de noSQL con los de estructuración de equipo para que haya variedad.



Buen post y coincide con mi experiencia.
Me interesa tu opinión sobre el cómo. Quiero decir, ¿cómo convencer a los de sistemas, BBDD, host y distribuidos de poner un sistema de persistencia no relacional?
Claro, necesita tiempo y dar la lata continuamente, pero ¿ves alguna estrategia para hacerles entender la diferencia entre la solución a un problema y la eterna costumbre de ‘siempre se ha hecho así’?
Simplemente tienes que tener claro si tu aplicación necesita una BBDD relacional o no. Si necesitas consistencia y ACID, no tienes unos requisitos de escalabilidad y disponibilidad altos y no tienes un core de negocio OO con lógica dentro, entonces usa una BBDD relacional. Si no, prueba a usar una noSQL como simple almacén de persistencia, y se te presentan dos opciones para presentarlo al cliente:
En general el departamento de BBDD estará en contra ya que lo verán como una amenaza y un camino para que ellos pierdan poder. Sin embargo ésta actitud no tiene futuro si realmente las aplicaciones pueden hacerse más baratas y tener mejor rendimiento con noSQL. Sólo hay que darle tiempo al tiempo.
Muy buen post. Lo que mas me ha gustado es la argumentación hasta llegar al porqué de usar noSQL. Está claro que no hay solución que valga para todo pero twitter, facebook, google y sus sistemas distribuidos estan evolucionando a todo esto…¿por algo será no?.
Seguiré atento a futuros post. Creo que en algún momento tendrás que encajar los Repositorios Distribuidos + Equipos distribuidos + sistemas noSQL….todo va hacia el mismo sitio…
Sí, tengo que hacer un post viéndolo todo en conjunto, ¡ pero aún no he escrito nada sobre el control de versiones de código fuente distribuido ! Y pretendo seguir dando la lata con el tema de la organización de equipos, tema que creo está muy subestimado frente a la tecnología en si.
Has dado con un tema espinoso. Ha sido tema de debate en el último año entre el equipo de arquitectura BBDD y el de Desarrollo en el cliente en el que estoy. Nuestros argumentos -los de arquitectura JEE ó Desarrollo- son más o menos los que has puesto tú (más las ventajas de mantener aplicaciones OO contra mantener procedimientos almacenados). Los suyos se basan precisamente en la posibilidad de ejecutar lógica de negocio en la BBDD ¿por qué tener la ejecución de la lógica en un lugar separado de donde están los datos?. El “lugar separado” es la aplicación, claro, o el runtime (servidor de aplicaciones, por ejemplo) donde se ejecuta la aplicación. No puedo extenderme mucho con un simple comentario, pero estoy seguro de que vamos a ver cada vez más enconado este debate en los próximos tiempos.
Cierto, cada vez veremos más este debate. Lo que pienso que ocurre en el cliente en el que estás es que la aplicación de ellos son los procedimientos almacenados y las tablas y que la base de datos está actuando como su “servidor de aplicaciones”. Me dá la impresión que para ellos en JEE no es más que una capa periférica que actúa como pasarela o maquillador para su aplicación, un simple medio para conectar su aplicación a la web. Si a ellos esto les va bien, perfecto. El problema vendrá cuando quieran tener unos requisitos de negocio ágiles, time to market cortos y responder a cambios y arreglar fallos rápidamente. Para ello tendrán que usar técnicas como integración continua y TDD, y entonces se darán cuenta que tendrán que migrar su aplicación a sistemas que soporten estos conceptos. O también podrán entrar en fase de negación con las consecuencias que ello supone. Otra posibilidad es que estén en un sector de negocio que no requiera un modelo de negocio ágil, como la administración pública.
¿Cuantos años hace que hablamos de encapsular los datos y el negocio en objetos de negocio? ¿20 años? Quizas mas.
Dentro de las caracteristicas de las aplicaciones te olvidas de algo importante: la seguridad de los datos, la replicación remota de datos, el valor de los datos.
Los datos son la vida de las organizaciónes. Las aplicaciones que los explotan son algo transitorio y cambiante. No es lo importante.
Poneis como ejemplo amazon, google, ebay, facebook, etc.
Si alguna de estas aplicaciones deja de dar servicio por unos minutos, no pasa nada. Si desaparecen algunas fotos del Facebook, no importa se vuelven a subir. Si Goggle pierde algunas direcciones de correo, no pasa nada, es gratis.
Pero las trasacciones de banca internacional, de bolsa, de banca y seguros, de compañias de transporte, etc. ¡No pueden fallar!
¿Donde almaceno los datos de estos sistemas críticos para que me garantizen que se han escrito correctamente, que se han actualizado si lugar a dudas? En una BD que, seguro, será relacional.
Cierto, en el siguiente post analizo las transacciones ACID, que creo que tienen mucho que ver con lo que dices. Evidentemente el negocio del facebook no es el mismo que el de un banco o una aseguradora.
Lo que intento transmitir en este post es que los compromisos entre distintos factores (trade-off) son diferentes en distintos tipos de negocio, con lo que en algunos sectores puede no ser una buena idea usar una base de datos tradicional. Obviamente no es sensato decidir que las bases de datos estan “antiguas” y querer usar un modelo noSQL a toda costa.
Hay que pensar y decidir lo mejor de forma sensata, y que no nos afecten las modas, pero tampoco las tradiciones, a la hora de tomar una decisión de ingeniería.
Pssssssssss…. muy idilico….
Hola Manolete, he de decirte que yo al principio pensaba parecido…. “uy, esto es muy teórico…”, “en la realidad va a pasar esto…”. Bueno, empecé con el TDD y bien, pero claro el tema refactor era otra cosa “teorica”, era mejor un buen diseño “upfront”, que para eso soy arquitecto… Al final, después de pegarme muchas ostias, me decidí a hacerlo todo como debe ser, TDD+refactor+IC y la cosa va como la seda.
Los posts suelo escribirlos para dar mi visión práctica de las cosas, todo lo que cuento me ha pasado de verdad, en la práctica. Ciertamente a veces me sale la cosa un poco teórica, pero tened en cuenta que no puedo dar nombres…
Estoy confundido ¿Cuál es la diferencia entre un core de negocios y la lógica de negocios?
Suponiendo que tengo un sistema “sencillo” como el de una tienda tipo club donde los papás ven el historial de compras de sus hijos y/o sus esposas… Las esposas tiene tarjetas de créditos
¿Es factible utilizar una base de datos orientada a documentos como mongoDB?
Por aclarar lo de core y lógica de negocio. Cuando digo lógica de negocio, me refiero a la funcionalidad fundamental del sistema (modelo de negocio, validaciones, reglas de negocio, etc). Esto evidentemente no sobra nunca, al contrario, es la parte más fundamental del sistema. Cuando hablo de “core de negocio” me refiero a un conjunto de clases y objetos que implementan la lógica de negocio, es decir, implementar la lógica de negocio como un núcleo de OO, como contraposición a meter la lógica en la capa de presentación o en la capa de persistencia (procedimientos almacenados y triggers).
Sobre lo de usar mongoDB, pues es totalmente factible. Pero te recomiendo que eches un vistazo a todas las que existen, sistemas noSQL hay muchos, y con prestaciones y funcionalidades diferentes. Ten en cuenta tus necesidades reales de escalabilidad, tiempos de respuesta, nivel de consistencia y robustez. Echa un vistazo a Cassandra, MongoDB, CouchDB, Voldemort o Neo4j.
excelente post y dejo una pregunta.
Estoy buscando pequeños ejemplos para hacer cada vez menos uso de la BBDD relacional. Siempre que puedo uso archivos de texto planos.
Dejo una pregunta:
¿Como haríamos esto en un nosql ?
como hariamos esto?
ID CATEGORIA VALORHORA
– ———– ———
1 Junior 10.0
2 Semi-Senior 20.0
3 Senior 30.0
ID NAME USERNAME CATEGORIA_ID
– ——- ——– ————
1 gustavo gus 1
2 carlos car 1
3 mariana mar 3
4 pamela pam 2
5 roman rom 2
me interesa mucho el tema de NoSQL
es mas estoy comenzando un proyecto de comparacion con SQL
el cual estara apoyado con encuestas hacia publico en general en algunos casos sobre redes sociales-google-amazon y en otra encuesta sobre el conocimiento que se tiene sobre este tipo de Base de datos
seria interesante si me ayudaras con esto, nose recomendanme paginas donde colgar mis encuestas de modo que pueda obtener datos para mi proyecto