Carlos Ble

Carlos Ble

I am a professional software developer, I solve problems.

I also teach and mentor developers to build better software.

Working as an independent professional since 2009.

Can I help you?

  • Do you need high quality tailor-made software?
  • Need training on TDD, clean code or refactoring?
  • Is it risky? do you need advise?
  • May I pair with you to write better code?

Events

Upcoming public training courses:

  1. [in English] May 5, 6 & 7
    TDD - Train the Trainers (iSQI)
    Potsdam, Berlin
  2. [en Español] 23, 24 y 25 de Abril.
    Curso de TDD con examen de certificacion iSQI
    Madrid
  3. [en Español] 29, 30 y 31 de Octubre.
    Curso de TDD con examen de certificacion iSQI
    Madrid

Conferences:

  1. I'll be at SocratesUK 2014
  2. I'll be at the London Test Gathering Workshops.

Diseño emergente, también para la base de datos

Nota: Me apetecía escribir este post en inglés pero me surgió la siguiente duda.. ¿cuántos de los visitantes hispano parlantes dejarían de leer el post por estar en inglés? Si lees este post y te resuta de ayuda estaría bien que añadieses un comentario diciendo si lo hubieses leído en inglés tambien. Así puedo tener feedback sobre si escribir más en castellano o con mi inglés chungo.

Aunque las bases de datos No-Sql están a la vanguardia, muchos seguimos usando también Sql y seguirá siendo así porque Sql y No-Sql tienen ventajas y desventajas. Sin embargo habiendo trabajado con ambos paradigmas, me he llevado cosas que he aprendido con No-Sql a Sql y la ventaja es muy "agil" :-)

Normalmente las bases de datos Sql se diseñan normalizadas, es decir, se evita la duplicidad de datos mediante tablas que se relacionan entre sí con claves foráneas y demás restricciones. Unas tablas apuntan a otras mediante los identificadores y estas cosas. La ventaja de la normalización y de las restricciones tipo "unique", etc, es que no se repiten datos y por tanto el motor optimiza el acceso a ellos. Además podemos mantener una cierta integridad de los datos evitando que se inserten datos sin sentido.
La desventaja es que los cambios estructurales en la bd cuestan muchísimo. Hay herramientas de migración automática que funcionan bastante bien cuando los cambios son relativamente sencillos pero hay migraciones muy complicadas.

Ahora bien... ¿con qué frecuencia hay que hacer cambios en la bd cuando estamos en pleno desarrollo? Pues en cada iteración. Cuando la funcionalidad es nueva, practicamente cada dia o cada semana.
¿Y cuánto nos cuesta manejar en el código un diseño de base de datos complejo? Es caro, porque la optimización se paga con tiempo de desarrollo. Una base de datos es compleja porque tiene relaciones.
Cargar con relaciones entre tablas desde el inicio es muy caro. Diseñar una bd normalizada desde el inicio me parece tremendamente ambicioso, demasiado optimista. Me supone crear capas de anticorrupción para que la lógica de negocio no se vea afectada por la extrema complejidad del esquema de datos. Me supone mucho tiempo en las migraciones.

Personalmente prefiero crear bases de datos los más planas posibles, que me permitan
desarrollar muy rápido y hacer cambios sin problemas de migraciones. Una vez que el feedback de los usuarios me dice que ya conozco suficiente del negocio, de verdad, me planteo ir normalizando la bd para optimizar.
Para esto suelo crear un campo en la tabla de tipo texto, donde puedo guardar serializada toda la información que voy necesitando, usando un formato clave-valor. Luego en código cuando cargo los datos me encargo de deserializar e interpretar esos datos. Así cuando necesito quitar o poner un campo no tengo que tocar la estructura de la base de datos. Ejemplo:
Quiero gestionar las tareas de un usuario. Un usuario debe tener un nombre unico, algunos datos de contacto y puede tener muchas tareas. Cada tarea tiene una serie de datos, de momento titulo y descripcion.
Esquema de BD inicial:

Estructura Tabla user:

field type
id Pk, autoincremental...
username varchar(50)
fields text
userdata text

Ejemplo de una fila rellena en la tabla:

id username fields userdata
0 fulanito email=fulanito@gmail.com#age=20#phone=30 {tasks: [{'title': 'un titulo', 'description': 'probando'}]}

En el campo "fields" de la tabla voy poniendo lo que creo que son campos de esta tabla, separados por el simbolo #. Si necesito poner o quitar campos o necesito que unos objetos tengan un campo y otros no, no tengo que tocar la BD.
Para gestionar este tipo de campos tengo una clase que sabe leerlos y transformarlos en un diccionario por ejemplo y luegos los "getters" de mi objeto de negocio los puedo implementar consultando a ese parser. No importa que use algun tipo de ORM, normalmente admiten métodos en los objetos de negocio.
En el campo "userData" he metido informacion en formato "json" (por poner un ejemplo de formato) que me permite guardar cualquier cosa.

La desventaja de esto es que cuando haya varios usuarios, habra datos duplicados. En la versión normalizada tendriamos una tabla User con varios campos, una tabla Task. Si la relacion es de muchos a muchos, ademas necesitamos una tabla UserTasks que una ambas. La otra gran desventaja es que si tengo que hacer ciertas consultas, las tendre que hacer en código en vez de usar SQL.

La ventaja es que puedo desplegar nuevas versiones sin preocuparme por las migraciones estructurales de base de datos. Puedo retrasar la normalización de la base de datos hasta que de verdad conozca lo suficiente del negocio. De esta manera consigo el esquema más simple posible que me permite programar con comodidad y que a la vez está optimizado. No tengo que cargar con sobreingeniería.

Si normalizo primero, igual decido crear la tabla UserTasks para que exista una relación de muchos a muchos. Si mas adelante las estadisticas de uso de nuestra aplicación y el conocimiento que tenemos de nuestros usuarios nos dicen que una tarea no la pueden tener dos usuarios, entonces hemos sobrediseñado.
Tenemos una tabla que no sirve. El problema es el coste que tiene mantener un código que hace frente a un requisito innecesario.

A menudo se piensa en el coste que tiene escribir una funcionalidad. Pero muy pocas veces se mide el coste que tiene mantener código que no se usa. Y en mi experiencia es un coste altísimo que te hace ir lento. Es una bola de nieve.

Para ir del esquema desnormalizado al normalizado, la prioridad es ir creando campos en las tablas para aquellos atributos por los que quiero poder hacer consultas. Por ejemplo, si nunca hay necesidad de buscar por el numero de telefono, este campo no tengo por qué extraerlo a un campo de bd. Incluso puede que nunca.

Por otra parte, para argumentar sobre el rendimiento de la BD, como con muchas otras cosas, conviene tener datos empíricos objetivos. Es decir, no voy a trabajar en un problema de rendimiento hasta que no haya hecho pruebas de estres o de carga y tenga unos datos que vemos que no son buenos y que hay que mejorar.
A menudo, optimización y rendimiento son enemigos de mantenibilidad. Por eso en mi opinión y mi experiencia (a base de equivocarme) sólo hay que optimizar cuando hay algo que ya funciona bien.

Esta forma de evolucionar las bases de datos puede suponer para algunos hacer las cosas al revés. Lo que ya les pasa con algunas prácticas como TDD. Sin embargo cuanto más experiencia tengo más pienso justo lo contrario, que he pasado demasiado tiempo haciendo las cosas al revés.

Hay que poner en perspectiva lo que uno aprende en la universidad porque a veces son conceptos de hace muchos años, que ahora tienen que ser revisados de otra manera.

Enjoyed reading this post?
Subscribe to the RSS feed and have all new posts delivered straight to you.
  • https://eamodeorubio.wordpress.com/ Enrique Amodeo

    Hola Carlos, me parece a primera vista que lo que propones no es más que emular una base de datos documental sobre una base de datos relacional. ¿Por qué no usar directamente una base de datos documental, como por ejemplo MongoDB? Te permite consultas por clave primaria y por índices, pero no soporta join. Es decir, está diseñada especificamente para afrontar la persistencia con exactamente la misma estrategia que estás usando.

    Mmm… tengo que escribir un post de réplica sobre esto…
    Salud!

  • http://carlosble.com Carlos Ble

    Y que sucede si en mi proyecto ya usamos SqlServer para muchas otras partes que ya estan desarrolladas y que hay que mantener y las partes nuevas tienen que nutrirse de datos de ahi? (y viceversa).
    Tu idea me parce genial para un “green field project” :-)

  • http://www.programandonet.com Pablo Bouzada

    Hola Carlos, me parece una idea muy buena, sobre todo en las primeras fases de desarrollo cuando van surgiendo requerimientos no esperados que te obligan a añadir o quitar relaciones/campos/tablas, lo que suele resultar muy traumático.

    El problema es que, como dices, estamos muy acostumbrados a hacer las cosas “al revés”, sobre todo cuando usamos grandes RDBMs como SQL Server u Oracle. Parece que la única forma de hacer las cosas sea normalizando hasta la 3ª forma y luego mantener un proyecto adicional para el mantenimiento de la base de datos.

    PD: lo habría leído en inglés, y dudo mucho que el tuyo sea mucho peor que el mío :P

  • Tomás

    El post mucho mejor en español, así me resulta más fácil quedarme con la “chicha” ;)

    Por otro lado quizás te interese usar Liquibase (http://www.liquibase.org) aunque estoy seguro que ya lo has usado.

  • http://carlosble.com Carlos Ble

    Hay una cuestion mas por la que en este proyecto no puedo coger Mongo y es que sabemos que vamos a necesitamos hacer consultas complejas que ademas deben ser bastante rapidas. Es porque el negocio tiene una casuistica muy compleja y para temas de inteligencia de negocio y demas, vamos a necesitar toda la potencia del sql relacional. Mi propuesta es simplemente esperar a optimizar cuando ya sabemos lo que usamos con exactitud y no antes.
    Es decir, no siempre una base de datos documental puede suplir a una relacional.
    Para muchas web startups esta de puta madre, creo que para la mayoria, pero en este caso estamos resolviendo un problema con una casuistica realmente compleja.

    No he usado liquidbase pero he usado otros. La verdad que son una buena ayuda pero prefiero no tener que usarlos, porque no siempre me pueden dar la solucion que necesito.
    No obstante creo que esta claro que hay que usar un gestor de migraciones de bd como liquidbase, cuando trabajamos con bd relacionales.

  • https://eamodeorubio.wordpress.com/ Enrique Amodeo

    Ja, ja, :-) Sí, es verdad, hay que adaptarse a lo que ya tienes e ir cambiándolo gradualmente. La gran ventaja del relacional son los joins y el “tipado” de las columnas, si no lo vais a aprovechar, ¿qué ventaja os da el relacional sobre otros modelos? Pero entiendo que si tenéis que convivir con más cosas prefieras un enfoque menos agresivo.

    De todas formas si seguís por este camino, llegará un momento en que toda la BBDD esté diseñada de esta forma, y entonces será el momento de plantearos cambiaros a otro tipo de base de datos.

    Salud !

  • http://frosas.net/ Francesc Rosàs

    Una técnica muy interesante. Seguro que muchos hemos hecho algo parecido de forma inconsciente en esos casos en que meter cada cosa en una tabla/columna se hace claramente excesivo (por ejemplo, para guardar las preferencias del usuario), pero no creo que muchos hayan considerado hacerlo así por defecto.

    Te has encontrado algún problema al normalizar posteriormente? Trabajas con algún ORM tipo Doctrine? Se adapta bien a este modelo?

    Sobre lo de escribir en inglés, adelante, aunque a lo mejor el número de comentarios se resiente.

  • http://frosas.net/ Francesc Rosàs

    Enrique, eso de que al final toda la BD acabará “desnormalizada” no acabo de verlo. No será más bien al revés? Se empieza con un todo desnormalizado y se normaliza en la medida que haga falta (para los joins, filtros, ordenaciones, campos/tablas demasiado grandes, …).

    Por ejemplo, para un blog (con usuarios, blogs, entradas, comentarios y tags) con las funcionalidades típicas seguramente la BD acabaría muy normalizada (ojo que no digo que no se pueda hacer con una BD documental!)

  • http://frosas.net/ Francesc Rosàs

    Por cierto, qué formato usáis en los campos desnormalizados? Habiendo probado con el serializado de PHP, JSON y YAML, personalmente me quedo con YAML por ser el más fácil de leer y editar directamente.

  • http://www.aramirez.es Alberto Ramírez

    Hola Carlos, me parece muy interesante ese enfoque de ir aprendiendo del primer feedback de usuarios para luego normalizar. Tengo dos apuntes básicamente:

    - El producto donde pruebas este sistema ha de ser una beta restringida, spike o similar, de lo contrario, si se trata de un producto abierto a todo el mundo te expones a que el volumen de datos crezca exponencialmente, y que a posteriori la normalización se convierta en un auténtico quebradero de cabeza, más quizá que siguiendo el enfoque tradicional.

    - El proceso de normalizar la base de datos debe ser costoso, no solo implica muchísimo cambio a nivel de base de datos (estructura de las tablas, relaciones y migración de datos) sino que también requiere esfuerzo a nivel de código, es decir, si tienes un datamapper por cada tabla que transforme los datos (row > mapper > value object) y los haga “entendibles” por tus objetos de negocio también han de cambiar. Realmente, ¿Es este esfuerzo menor que el de andar con migraciones tradicionales?

    Sin duda me parece muy interesante el enfoque. Saludos!

  • Guillermo

    Carlos:
    As you´ll read, my english is worst than yours surely.
    I think the article is very good, and it will be as good on any language so, why not to have both versions?
    I can´t agree totally with you on developing a parser instead of modifiying structures, i don´t know…
    Is like this article from Uncle Bob on his 8lght´s Blog.
    It worth a read, i agree mostly with it…
    We have to program for the solution, not the database.
    http://blog.8thlight.com/uncle-bob/2012/05/15/NODB.html

    Guillermo

  • http://www.eferro.net Eduardo Ferro Aldama

    El tema de tender a usar siempre relacionales es cuestión de que lo tenemos metido a fuego en el subsconsciente. A mi sin embargo me causa casi siempre desasosiego (por lo menos el usarlo por defecto), puesto que la gran ventaja que le veo es poder desde varias aplicaciones tratar los datos y consultarlos de formas que ahora no puedo anticipar… por otro lado, este uso, lo intento evitar puesto que no quiero que se produzcan “integraciones” mediante base de datos…

    Así que creo que es cuestión de particionar y ver si necesitamos persistencia de objetos, datos planos, esquemas para OLTP, para OLAP… y elegir lo que se necesite para cada aplicación, pero sin opciones por defecto que arrastremos como un lastre …

    Caminando hacia http://martinfowler.com/bliki/PolyglotPersistence.html

    P.D. También lo hubiese leido en inglés

  • Lars

    Se agradecería un ejemplo concreto con el código para descargar. Sinceramente, tal y como lo planteas me suena a trabajar dos veces en general, como poco.

    En inglés seguramente no lo habría leído entero. En general, tanto en español como en inglés, leo el titular, ojeo el primer párrafo y si identifico con rapidez qué tiene de interesante pues sigo leyendo. Si es en español suelo dar más margen y quizás leo hasta el segundo párrafo.

    Al final con esto del RSS estás suscrito a muchas webs y la cantidad de información a procesar cada día es enorme. Si no se va al grano desde el principio acostumbro a descartarlo.

  • http://blog.elfilo.net patxangas

    Prefiero en Castellano. Blogs que solo escriben en ingles sigo unos cuantos y de vez en cuando me agrada leer post de este nivel en un idioma que me apaño mejor.

  • https://eamodeorubio.wordpress.com Enrique Amodeo

    Francesc, el tema de normalizar y los joins es para hablar largamente sobre él. Normalizar es bueno para ahorrar espacio de almacenamiento, pero es malo desde el punto de vista de la escalabilidad ya que te obliga a hacer joins. ¿Qué es lo más rentable para vosotros? ¿Diseñar para optimizar el espacio ocupado en disco o diseñar para optimizar la escalabilidad? La respuesta depende mucho del tipo de aplicación, pero me atrevo a decir que en la mayor parte de los escenarios en una aplicación web lo más importante es la escalabilidad.

    Después hay otros temas, como la productividad del desarrollo, y el coste de mantenimiento. Carlos en este post nos comenta las ventajas que obtiene en su proyecto al relajar los requisitos de normalización. También me atrevo a decir que normalmente los costes de mantenimiento son más importantes que los costes de almacenamiento.

    Finalmente, en arquitecturas CQRS y DDD, el tema de la normalización se resuelve de otra manera, y los joins dejan de ser útiles.

    Salud !

  • http://virtualminder.wordpress.com Antonio Martínez

    Me parece muy interesante el post y legible para todos los públicos. Yo he vivido casos de 10 tablas para 100 – 200 registros y de una para 1 millón. Creo que este enfoque permite solucionar ambos modelos de forma elegante y adaptable.

    Hubiera preferido el post en Inglés, por dos razones, para mejorar mi nivel y para abrir la puerta a más comentarios que siempre enriquecen. Entiendo que exige más esfuerzo al escritor y a lector castellano pero también tiene una audiencia potencial (no digo real) más extensa.

  • Richard

    En mi opinión las base de datos SQL y No SQL tienen su uso cada una, aunque los podamos mezclar una viene mejor para unos cosas igual que otras para otros.

    De igual manera una base de datos no normalizada contra una normalizada puede tener sus usos.

    Una vez trabajé con un sistema bancario en el cual el servidor que manejaba las transacciones (como podrán imaginar muchas por segundo) tenia una estructura de tablas no normalizadas, lo cual permitía una escritura de datos muy rápida, pero contaba con un proceso que luego tomaba los datos y los pasaba a otro servidor el cual contenía una BD con una estructura normalizada, este segundo servidor se encargaba de manejar las consultas de datos, realización de reportes, históricos etc… Una estructura normalizada por lo general está optimizada para realizar consultas rápidas.

    Una vez alguien me comento una idea parecida, el guardar en tablas “objetos serializados” y luego deserializarlos para obtener la información, pienso que puede llegar a servir para casos muy específicos, pero desde mi punto de vista la forma en que lo plateas me parece un retrabajo, aunque si te ha funcionado hurra :D .

    Suelo leer blogs en Ingle y Español, pero cuando son temas “profundos” de programación los prefiero en español

  • https://eamodeorubio.wordpress.com Enrique Amodeo

    Los esquemas normalizados no sirven para que las consultas sean rápidas, sino que más bien, entre otras cosas, te dan flexibilidad a la hora de escribir consultas no anticipadas.

    Ahora bien para que las consultas vayan “rápido” hay que definir índices, y claro, qué índices definir dependen de que consultas tengas. Si no tienes todas tus consultas claras por anticipado, y si el usuario tiene opción a definir sus propias consultas en tiempo de ejecución, no podrás definir los índices óptimos, y por lo tanto tus consultas no serán “rápidas”. En general los DBAs no son muy amigos del SQL dinámico.

    De hecho, después de unos cuantos ciclos de optimización, es típico que el DBA te pida que desnormalices tus tablas, por motivos de rendimiento. Me ha pasado un par de veces.

    O sea, Carlos hace muy bien en empezar con un enfoque que le permita evolucionar rápidamente, el rendimiento ya se arreglará cuando haya problemas, y normalmente no va a implicar normalizar.

    A pesar de lo que digan los comerciales que las venden, las BBDD relacionales no son mágicas, ni te dan rendimiento gratis.

    Me siento un troll, pero no me pude resistir! :-)

  • http://twitter.com/jneira jneira

    Mmm ¿y la opcion de tener dos bases de datos (o dos esquemas)? Una mientras se esta desarrollando la aplicacion y la otra mas “estable”. Si la migracion entre las bbdds o los esquemas no es muy problematico y la aplicacion usa un orm que te permite cambiar sin mucho coste a traves de la configuracion el esquema o la bbdd no se si podria ser una opcion…

  • http://jose-juan.computer-mind.com josejuan

    Me ha parecido muy interesante. El problema es bien conocido, aunque la agudeza del mismo depende de muchos factores.

    De todos modos, creo que hay un mejor enfoque (que es el que yo uso, claro XD XD XD) y no es más que mantener una tabla de registro (hay gente que usa sólo una global, a mi me gusta mantener también en algunas entidades especiales).

    Viene a ser como el registro (“regedit”) de Windows, defines “clave/valor” y listo.

    Viene a ser lo mismo que lo que propones, pero mejor; porque puedes simular sin problemas una tabla que no existe.

    Por ejemplo, supongamos que cuestionamos la necesidad de almacenar los cambios realizados en la tabla USUARIO, para ello tendríamos que tener una tabla USUARIO_HISTORICO (o algo así), en tu caso, lo metes todo en un campo impidiendo el procesamiento con SQL (serialización), en mi caso, tendría una tabla USUARIO_XDATA (o si usas la global GLOBAL_XDATA) con claves {old.usr..name, old.usr…password, etc…}.

    Donde es la clave primaria de USUARIO e es el ordinal de los cambios realizados (1er cambio, 2º cambio, …).

    Puedo obtener una tabla a partir de esos datos con un simple PIVOT TABLE.

    Si luego se elimina del modelo, sólo tengo que hacer un DELETE FROM USUARIO_XDATA WHERE Key LIKE ‘old.usr.%’; por contra, si se quiere mejorar e integrarlo “relacionalmente” añado la tabla USUARIO_XDATA ¡que además puedo crear desde mi PIVOT TABLE!.

    Las tablas “registro” siempre las tengo en producción, vienen bien para meter información “extra” en todo momento.

    En cuanto al rendimiento, si es preciso, lo suyo es mirar de ajustar el modelo, de todos modos, ya he comentado que puedes crear una vista cacheada con PIVOT que virtualmente seriviría para los mismos propósitos prácticos (y de rendimiento).

    En cualquier caso, a mi nunca me ha supuesto “mucho” problema reestructurar la bbdd, en realidad el problema es mucho más amplio pues involucra procesos (lógica de negocio) e interfaces de usuario.

  • http://jose-juan.computer-mind.com josejuan

    (Vaya, se ha comido texto, reescribo el trozo)


    tendría una tabla USUARIO_XDATA (o si usas la global GLOBAL_XDATA) con claves {old.usr.USRPK.ID.name, old.usr.USRPK.ID.password, etc…}.

    Donde USRPK es la clave primaria de USUARIO e ID es el ordinal de los cambios realizados (1er cambio, 2º cambio, …).

  • http://jose-juan.computer-mind.com josejuan

    (estoy tonto)

    Obviamente las claves “old.usr.USRPK.ID.name” son en caso de usar la tabla GLOBAL_XDATA, si se usa USER_XDATA serían “old.usr.ID.name” pues “user_id” pertenecería a “USER_XDATA”.

    Bueno se ha entendido, creo…

  • http://develandbeyond.wordpress.com Pablo C.

    Carlos, no puedo estar mas en desacuerdo.

    Lo siento pero, qué le vamos a hacer?, soy un “DBaero” aférrimo.

    Entiendo los (¿el?) argumento(s) pero no estoy en absoluto de acuerdo, veo el ejemplo de los usuarios y me duelen los ojos… entiendo que también habrá que currarse algo en desarrollo para actualizar ciertos campos de esos que están en “fields” con un where (que además que irá con un like y que se complicará mas aun si encima quieres buscar por ooootro de esos campos de “fields” o de “userdata”) algo que TAMBIÉN se traduce en mas tiempo de desarrollo (no era ese el argumento?), por no hablar del descenso en rendimiento.

    Al final todo se reduce a tirar o no de un DBA.

    Por otro lado… de qué cambios en BD hablamos?… nuevos campos?… no problem (ALTER TABLE etc.), eliminar campos menos problema, pasar campos de una tabla a otra? (ALTER + update + DELETE)… pero imaginemos que, por ejemplo queremos pasar de tener controlado los apellidos en un solo campo a tenerlos en dos, por ejemplo, cómo de fácil es en tu sistema?… porque creo que excepto por un par de alter’s que quitemos, el tuyo tiene algo mas de chicha (a no ser claro que lo hagas por programación).

    Sinceramante creo que hay que pensar en tener una persona que haga las veces de DBA para esas iteraciones tan “”complejas”" y fin del problema.

    Estoy abierto a estas “nuevas olas” pero necesito argumentos un poco mas de peso que “es que hacer un cambio complejo es costoso” (habrá que preguntarse cuanto costó hacer la clase esa… y cuando cuesta un licencia de “redgate sql toolbelt ” o de “apexsql tools” que, por cierto, funcionan genial con MsSQL)

    Un saludo

  • http://carlosble.com Carlos Ble

    Es muy interesante leer las propuestas sobre cómo lo hace cada uno. Me quedo con ideas muy muy interesantes.
    Para los que pensais que es doble trabajo, es porque creo que estais pensando que al final vais a tener el mismo esquema normalizado que tendriais desde un primer momento. Si asi fuera, entonces ciertamente seria el doble de trabajo. Entiendo que eso es porque no habeis probado a escribir código minimalista, por ejemplo siguiendo la regla de no escribir ni una sola linea mas de código que la que te pide un test en rojo. Cuando haces eso te das cuenta de que hay un nivel de simplicidad mayor que el que uno creia y eso produce un código aun mas simple. Esa simplicidad tambien se traduce al esquema de BD.
    Asi que no tengo el doble de trabajo, sino un proceso a traves del cual llego a construir el esquema de BD más simple posible y a la vez mas eficiente.
    Se trata de un proceso de diseño emergente. Si lo sigues bien, el resultado del esquema al final, no deberia ser el mismo que haciendo el esquema a priori.

    Todo esto es mas dificil de encajar dependiendo del punto de experiencia en el que cada uno se encuentre. La implementacion tambien puede variar y tener algo más intermedio, por ejemplo algun campo puede estar en su propio campo si estamos convencidos que hay que hacer queries por el. No tienen que estar absolutamente todos serializados en “clave-valor” si ya tenemos el conocimiento.
    El cuidado hay que tenerlo en saber si de verdad tenemos el conocimiento o si es una suposicion. En mi opinion aqui es donde peca siempre el de poca experiencia.
    Yo soy mas bien hombre de poca fe en cuanto al diseño infalible e impecable desde el inicio. Prefiero ir haciendo sólo lo que conozco que hay que hacer.
    Cuando dejas de “escribir una linea de código por si acaso”, consciente del coste que tiene mantenerla aunque no se use, tambien te planteas las cosas de otra manera.
    Esto de escribir software es aprender constatemente.

  • Diego Güemes

    Me ha gustado mucho el post, creo que encaja perfectamente con los principios YAGNI y KISS.

    Aunque soy un paquete con el inglés, tus otros posts los he entendido perfectamente, y creo que llegarías a más gente de esa forma. Además tenemos que empezar a admitir, que la profesión que hemos elegido, se escribe en ese idioma :D .

    Por cierto Enrique, a ver si te animas a publicar algo sobre lo que comentas de CQRS y DDD, a algunos nos vendría de perlas.

    Un saludo y gracias por el post!

  • GreenEyed

    Yo estoy con Pablo C., que le vamos a hacer :) . Con las herramientas adecuadas, hacer cambios en la BDD no es tán sumamente complejo como para que simplemente teniendo los campos serializados no haya que hacer nada, a cambio del coste de desarrollo y rendimiento en ejecución.

    Para eso te puedes plantear desarrollar en Grails/Roo o alguna solución similar donde tu escribas las clases y el esquema de tablas te lo genere el solito.

    Y el tema no es normalizar o no normalizar, es si pones muchos de los campos en columnas o los metes en uno de texto serializados. La normalización es otro tema que ya uno tiene que tener pensado antes de meterse en una BDD relacional o no, por que si no para que usar una relacional (sí, salvo los casos excepcionales por rendimiento extremo, que deberían ser contados).

    PD: En inglés me lo hubiera leído igual por que soy básicamente bilingüe, aunque en caso de hacerlo, es bueno hacerlo con algo de cuidado para no hacer “el ridi” y si lo haces para aprender, fomentar y aprender de las críticas, por que si no, no se aprende. IMHO, obviamente.

  • http://www.magmax.org Miguel Ángel

    Hola a todos.

    ++English, pero… ¿por qué no ambos?

    Tu artículo: los tienes mejores. Pero has provocado una avalancha de mensajes muy interesante :D

    Las BBDDs relacionales te ofrecen tipado y joins. En una BBDD no-sql hay trucos para hacer joins a mano, y el tipado… nada lo diferencia de hacerlo a mano. A mí me gusta crear una capa de abstracción, que me permita realizar operaciones de más alto nivel que acceder a una única tabla.

    Los ORMs son geniales… hasta que los usas. Para una aplicación pequeña, molan. Cuando crece, se hace lento y pesado. Pero tienen la ventaja de que cambias de base de datos fácilmente (en teoría).

    He usado muy poco las bases de datos no-sql: a penas un par de ejemplos en HBase. Pero me ha parecido bastante interesante el enfoque. En mi último pet-project estoy usando python-shelve, que no es más que un diccionario persistente. Cuando tenga la aplicación más o menos definida, puedo decidir cambiar ese formato, que solo debería costarme cambiar mi capa de abstracción. Sin embargo, si no tengo problemas de rendimiento… ¿por qué cambiarla?

    Otra opción más: ¿Por qué no usar dos bases de datos, una sólo de lectura (desde tu aplicación)? Puedes lanzar procesos en las horas de menos carga que metan los datos en esta base de datos “de solo lectura”. Para eso puedes usar una cola de mensajes (ActiveMQ, RabbitMQ, ZeroMQ, …) e ir procesando las tareas cuando tienes recursos para ello. Tendrías la desventaja de la latencia hasta que los datos están disponibles.

  • Guillermo

    Sigo opinando que el punto principal de la solución tiene que ser la solución y no el almacenamiento de los datos.
    Generamos soluciones y valor, no desarrollos adaptados a un sistema de persistencia.
    Respecto a los ORM, me parece que están haciendo un trabajo grandioso en ese punto, mas allá de que sean mas pesados que un simple Datamapper o un Active Record codificado en casa.
    Hay soluciones livianas que reemplazan a los mas grandes del mercado (Hibernate, Entity Framework, y demás) si no estamos buscando grandes soluciones.
    Y creo particularmente que Code First de Entity Framework está dando mucho que hablar respecto al tema.
    Permitiendote un desarrollo “casi” limpio respecto el sistema de almacenaje que se va a usar para los datos.

  • Guillermo

    Una mas, y no molesto mas.

    Primero hay que resolver el problema, después decidir donde lo guardo.

  • http://www.carlosble.com Carlos Ble

    Leyendo algunos comentarios parece que no se ha entendido la idea del todo. Para actualizar datos no tengo que hacer nada con sql. De hecho lo que evito es usar sql hasta que es realmente necesario. Los objetos de negocio (a veces se les dice modelos) saben como manejar la información, lo puedo hacer todo en código. Incluso gano en cobertura de tests unitarios que me suplen a muchos de integracion.
    No hago “where” + “like” para actualizar un campo, simplemente le digo a mi objeto que actualize tal campo y el tirara de un mapeador propio que es super sencillo y que actualiza el valor. La base de datos la trato como algo con el minimo de inteligencia/potencial posible.
    En cada caso podemos usar la solucion mas productiva a la hora de meter los datos en las tablas. Por ejemplo hace poco teniamos dos tablas existentes y surgio la necesidad de tener una relacion de uno a muchas entre ellas pero no sabiamos de que manera se iba a querer consultar mas adelante. Inicialmente solo sabiamos que habia que guardar la informacion. Entonces en una de las tablas habia un campo text con ids y separadores: “2#4#45″. Lo que significa que esa entrada tiene los elementos 2, 4 y 45 de la otra relacionados.

    Con respecto a la normalizacion, claro que tiene que ver con lo que estoy hablando. Si el usuario tiene unos datos de perfil, entre los que se incluye por ejemplo una poblacion, puedo tener todo en la tabla usuario o tener una tabla para las poblaciones. Si tengo tabla para las poblaciones, no hay nombres de poblacion repetidos.

    De cara a hacer rollbacks rapidos de versiones en produccion, no tener que preocuparse de los cambios estructurales de BD tambien es una ventaja grande. Esto lo aprendi usando una bd documetal.

    Digamos que cada objeto de negocio se mapea en la bd de la forma que le resulta más cómoda. Empiezo modelando comportamiento orientado a objetos y eso va a la base de datos de la forma que me resulte mas facil.

    Siempre hay una capa DAO o Repositorio que separa el acceso a datos del resto del negocio. Mi propuesta es postponer su implementación todo lo posible.

    Llevo años usando ORMs y distintas tecnologias, por eso encuentro este enfoque util, porque ya he probado mas cosas. Me resulta curioso que me recomienden grails a estas alturas como solucion, despues de que Ruby on rails lleva una decada en escena.

  • http://nestor.babuine.net Néstor Salceda

    A mi me gustaría aportar que existe un libro llamado “Refactoring Databases” que cuenta algunas técnicas para reducir el dolor y tratar de que la base de datos sea una parte que también evolucione. Os dejo enlaces aquí:

    http://databaserefactoring.com/
    http://www.amazon.com/Refactoring-Databases-Evolutionary-Database-Design/dp/0321293533

    Recuerdo también, pero poco, un artículo de Ron Jeffries que hablaba sobre retrasar la decisión de introducir una base de datos (tanto, que al final no era necesaria!).

  • Venky

    Yo, tras leer esto, no puedo evitar pensar en el infierno. De hecho, en un infierno muy concreto.

    Mi teoría es que existen ciertas prácticas, a veces aparentemente inocuas, que mantenidas a lo largo de un tiempo terminan generando uno entre varios tipos de infierno. Uno de ellos -voy a intentar no extenderme mucho- es “el infierno del éter de metainformación”.

    En el infierno del éter de metainformación, la teoría del éter ( http://en.wikipedia.org/wiki/Aether_%28classical_element%29 ) es correcta pero se refiere a la metainformación. Es decir, existe un “misterioso elemento invisible” -el éter- que realmente no podemos observar, pero que se supone que es el medio en el que se transmiten toda una serie de fenómenos físicos. En este caso, el almacenaje de metainformación.

    Veamos cómo se llega al infierno del éter de metainformación para entender claramente en qué consiste.

    Al empezar a desarrollar con una estructura como la propuesta, usando el ejemplo de la tabla ‘user’, nos damos cuenta de que es fácil, muy fácil añadir una propiedad más al campo fields. Esta facilidad es innegable. Basta añadir

    email=fulanito@gmail.com#age=20#phone=30#contact=yes

    por ejemplo, para indicar que algunos usuarios han sido contactados con fines comerciales, por decir algo. Es muy fácil. Es tan fácil, que nos sentiremos tentados de hacerlo *sin más*. Porque la carne es débil y el programador tiene poco tiempo y va a lo fácil y esto es *muy* fácil.

    El problema es que ‘contact’ es opcional. A diferencia de, por ejemplo, ‘email’ que al principio lo pusimos ahí sin más pero está cada vez más claro que es obligatorio. De hecho, la lógica cuenta con que ‘email’ esté ahí, si no hay que mostrar un error o lo que sea. No tener ‘email’ no es correcto en la aplicación. Pero ‘contact’ es opcional porque es más sencillo contar con que sea opcional en el código que andar metiendo ‘#contact=no’ en toooda la tabla. Eso no tendría sentido. No sería rápido.

    Así que, lo hacemos así. Y automáticamente hay una pieza de metainformación (el hecho de que ‘email’ sea obligatorio y ‘contact’ sea opcional) que hemos almacenado en el éter. Está ahí, en algún sitio. El código cuenta con ello pero no está establecido en ningún sitio en concreto. Yo lo sé explícitamente porque lo he puesto y si tengo memoria (que no siempre es el caso) lo recordaré. Pero en general, para el proyecto en sí, la información está en el éter.

    (Más aún, hay otra unidad de metainformación que se refiere a ‘contact’. Supongo que os la imagináis, ¿no?)

    La semana siguiente, Miguel, un hipotético compañero de proyecto, mete una opción más en el campo ‘batiburrillo’… perdón, en el campo ‘fields’. Es muy sencillo y lo hace. La historia es que un usuario puede tener más de un número de teléfono porque resulta que hay algunos usuarios con mucha movilidad que suelen tener 2 ó 3 teléfonos. Miguel aunque podría pensar en ‘#phone2=40#phone3=38′, decide que “es más sencillo” que la opción ‘phone’ pueda tener varios valores, así que opta por ‘#phone=30,40,38′ y añade el código necesario para -opcionalmente- tokenizar ‘phone’ cuando contenga alguna coma.

    Un par de meses después, las 8 personas que trabajábamos en el proyecto hemos añadido nuestras opciones, algunas obligatorias, otras opcionales, otras con formatos particulares, otras con ciertos valores válidos nada más…

    Toda esa metainformación la hemos ido almacenando en el éter. Y cuando es sólo un poco, puede que no pase nada. Pero unos meses y un equipo de más de 0 personas, pueden generar mucha metainformación. Y ya sabéis cuál es el problema del éter. La misma razón que lo hace genial como teoría: no es observable.

    Este escenario no tiene por qué darse, lo sé. Sin embargo, lo he visto ocurrir en más de una y de dos ocasiones. Aún más! He visto alguna ocasión en que a alguien le pareció tan buena idea, que montó todo un sistema similar de forma intencionada. Invirtió en optimizar una base de ese tipo y llevar esa plataforma a producción. 5 años después, desarrollar sobre ese sistema, para quien ya lo conoce es un pequeño infierno de notas de listas de sitios donde se debe tocar si se cambia la propiedad ‘x’. Para quien no lo conoce y no tiene esas anotaciones es uno de los infiernos más delirantes que se pueden encontrar.

    P.D. Respecto al inglés: A mi me parece bien. Recomendación: Busca a alguien que te revise. Se aprende mucho y se evitan problemas.

  • http://carlosble.com carlos ble

    Gracias por tu extenso comentario Venky.. Creo que esta basado en la premisa de no tener test automaticos. Yo tengo tests automaticos para expresar cualquier comportamiento que necesito darle a la aplicacion. Asi que no hay eter. Hay documentacion viva en forma de tests. A menudo las practicas que sigo serian deficientes o fragiles si no se apoyasen unas en otras. Por ejemplo el no escribir apenas comentarios en el codigo. Si no pusiese maxima atencion al codigo limpio y a los test autoexplicativos, seria negativo no comentar el codigo.
    Por eso cuando lees alguna de las practicas que sigo debes considerar el contexto y las otras practicas que la apoyan. No sacar de contexto en definitiva.

  • http://develandbeyond.wordpress.com Pablo C.

    Carlos, en una de estas, es que aún no llevo muy bien lo de los test (ya sean en java, c#, php o ruby) pero yo diría que los test unitarios… de tirar de BD “ná de ná”… vale… pensemos desde integración “pa’rriba” (funcionales, aceptación, etc). Bueno pues bien, tenemos una BD bien conocida, en YAML, SQL, o lo que cuadre y hacemos nuestros test con todo eso, vale, todo perfecto, el campo de “Miguel” (el compañero imaginario de Venky) está testeado y todo perfecto… subimos a nuestro servidor de integración (Jenkins, Hudson, Teamcity… el que cuadre vamos) y todo en “green”… perfecto todos felices.

    Ahora toca el turno de la MIGRACIÓN DE DATOS/ESTRUCTURA DE LA BD, y, yo me pregunto ¿qué tienen que ver los test con lo fácil o difícil que sea ahora migrar tu BD? (que era el argumento principal de todo esto).

    Lo siento pero es que quizás me he perdido algo.

    Un saludo.

  • http://carlosble.com carlos ble

    Pablo lo que trato de expresar es que esa migracion puede no llegar nunca. Puede que nunca haga falta. Entonces prefiero asumir el coste de la migracion cuando se que me hace falta, que el coste de un esquema complejo que no me llega a servir.
    Eso es lo que la experiencia me va diciendo.
    Ahora piensa tambien que la forma de definir los campos y las relaciones no tiene por que ser siempre serializando todo y demas. Hago hybridos cuando lo tengo muy claro desde un inicio, por ejemplo si ya hay un requisito de buscar por telefono.
    Respecto a los tests, cuando mis objetos de negocio serializan y deserializan, si que pueden ser unitarios porque son todo strings en memoria hasta el momento de salvar.
    Con un solo test de integracion me vale si solo hay un campo con los datos serializados.
    Conforme necesito migrar (si llego a necesitarlo) puedo ir cambiando unitarios por integracion.

  • carlos ble

    .Ayer justamente estaba escuchando un podcast sobre cassandradb y ponian el ejemplo de como poder hacer queries efecientes a pesar de la desnormalizacion. Ponian el ejemplo de recuperar los tweets mas recientes de las personas que sigues. Entonces lo que hacen es que ademas de guardar los amigos y sus tweets, guardan los ultimos tweets de ellos en otra tabla. Replican los datos en tablas diferentes tal que estan disponibles de la mejor forma posible para las queries que van neceditando. A esto se puede llegar con el ejemplo que yo proponia. Es decir que igual no hay que migrar el esquema siempre sino que ceñirnos al minimo de funcionalidad nos puede ir ayudando a evolucionar hacia soluciones mas interesantes y eficientes.

  • http://www.dvilchez.net dvilchez

    Hola Carlos,

    a mi personalmente no me convence. Asumes que por utilizar columnas y relaciones terminaremos con un schema muy complejo y con más elementos de los que tal vez necesitemos.
    Como he leído por ahí arriba lo importante es resolver el problema y después ya veremos como se persiste. Una vez solucionado el problema persisto mi modelo siguiendo los patrones y buenas practicas del tipo de BD en concreto (y no me refiero al modelo relacional), ni más ni menos. Y no haga nada para unas futuras migraciones que no se si voy a necesitar.

    Saludos,

  • http://carlosble.com carlos ble

    Hola David!
    En mi proyecto actual, donde el problema de negocio es muy complejo, el esquema de base de datos se diseño antes de programar las distintas funcionalidades y por supuesto se diseño normalizado. Eso ha hecho que todo se complique en exceso empezando por los tests. Teniendo en cuenta que tenemos que seguir usando sqlserver y campartir datos creo conveniente que las nuevas tablas que vamos usando no se definan del todo hasta que las releases van saliendo a produccion y vamos viendo que las necesidades del cliente van quedando satisfechas. Ademas las puestas en produccion ademas no son automaticas ni tenemos un gestor de migraciones automaticas ni un sistema para hacer rollbacks de version automatico en produccion, ni podemos desplegar unas partes independientes de las otras.
    Esta problematica me lleva a entender que esta solucion simplifica y reduce nuestros problemas. Tal vez en otro entorno, con un proyecto desde cero y mejores herramientas automaticas, usaria menos mis objetos para gestionar yo mismo la persistencia . Pero incluso en el caso mas favorable creo cada vez mas que la normalizaciom es parte del proceso de optimizacion y que la optimixacion llega despues de que estamos en produccion.

  • carlos ble

    A lo mejor es que di por hecho que todo el mundo diseña sus tablas antes de escribir la funcionalidad. Merefiero al menos a las tablas minimas para esa funcionalidad. Y lo que me parece mas importante por encima de todo es que no se diseñen antes sino despues. Si lo haces despues y te quedan varias tablas que de verdad necesitas, pues me parece bien.
    Fijate que cuestiones como que un campo deba ser unico, creo cada vez mas en que no deben estar en la bd, sino en el negocio, porque son reglas del mismo y yo no quiero que la bd sepa de negocio. Y si tiene que estar en la bd, que este tambien en codigo. Dejar la regla de “unique” en la bd y manejar en codigo las excepciones que vengan al insertar duplicados, me parece como programar usando excepciones pafa gestionar un flujo de ejecucion normal. Y ya sabes que el control de excepciones es para las situaciones inesperadas o excepcionales y no para programar flujos de ejecucion normales.

  • carlos ble

    Se me ocurre que en algunos casos puede funcionar bien el red-green-refactor a nivel integral, donde en el refactor puedes aplicar buenas practicas de bd, pero habria que tener cuidado de hacer refactor de verdad, es decir, sin introducir a nivel bd mas potencia de la que has añadido para hacer pasar el test.

  • http://www.estudiolibelula.com Eladio López

    Genial post y buen debate sobre un punto clave. A mi particularmente, que no tengo mucha experiencia con TDD, este tema se me atraganta especialmente. En cuanto a leerte, yo te leo aunque escribas en chino Carliños, pero sí te animo a escribir más en Inglés que le llegará a más gente. Además lo haces con total correción, aprovechaste bien esas pintas en Dublín :) .

  • http://carlosble.com Carlos Ble

    Gracias por el feedback Eladio! Ya me gustaria que fuera con total correccion pero bueno, creo que escribo algo entendible. Seguire alternando ingles y español en los posts :-)

    Un abrazo

  • Mariano

    Que bueno el articulo y los comentario. Aprendí mucho.

    Yo lo leería en ingles pero lo prefiero en Castellano.

    Gracias.

  • http://www.renderflow.com FidoX

    Bueno, yo llego un poco tarde al post ;) Pero también quiero dejar mi granito de arena. El caso es que soy incapaz de entender las motivaciones que argumenta Carlos para hacer eso que propone. Entiendo que puede ser que no me he visto en las situaciones que se está encontrando en su proyecto pero la verdad, no lo entiendo.

    Poniéndolo a modo de resumen porque en general se ha dicho prácticamente todo ya:
    * A mi tampoco me parece adecuado generar el esquema de la base de datos desde el principio. Yo lo hago cuando tengo un modelo de datos que me agrada. Como uso un ORM, simplemente anoto las clases del modelo y listo.
    * Si estamos haciendo tests de sistema, pues quiero asegurarme que el esquema también funciona así que los hago con el esquema definitivo, para esa versión claro. Los cambios se darán siempre. También me permite hacer tests de estrés al esquema de la base de datos.
    * Usar herramientas que me faciliten el trabajo, por ejemplo los ORM o http://www.liquibase.org/ para mantener el histórico de cambios en la base de datos y por supuesto http://kettle.pentaho.com/ para los casos que no se pueden resolver con SQL, (en realidad, prácticamente ninguno)
    * Sobre la normalización o no. Si el problema es de rendimiento hay muchas opciones antes: Las Tablas de agregados o el cache de consultas suelen darme mejores resultados.
    * Sobre definir reglas de negocio en la base de datos: En la medida de lo posible Sí. No para gestionar los errores, pero hay que tener en cuenta que la base de datos es un punto clave de la aplicación. En caso de un bug en la aplicación que afecte a la integridad de la base de datos pueden pasar dos cosas: Que tu aplicación deje de funcionar completamente por un caso totalmente inesperado (debido al bug) o que captures una excepción de SQL totalmente inocua que además te de pistas de que hay un bug en la aplicación. Eso no quita que tengas que hacer las validaciones pertinentes en la base de datos antes de grabar un registro. Pero es un muro de contención muy adecuado.

    Bueno, espero poder participar más a menudo en tu blog!
    Saludos.

  • http://www.carlosble.com Carlos Ble

    No coincidimos FidoX. Para mi la base de datos no debe saber nada del negocio :-)
    A cada uno le pesa su experiencia como es logico.
    Gracias por la contribucion, como a todos los demas que han dado su opinion.

  • Rafael Cano

    Buenas, yo ni sé de ORM ni de TDD y nunca he usado una base de datos NoSQL (cosas que quiero aprender en cuanto tenga un poco de tiempo). Llevo trabajando toda la vida con DBF y estos últimos 10 años con SQL Server. Soy programador de VFP.

    El meter un campo para añadir características a una tabla, me parece una idea, pero yo para ese caso tendría relaciones 1 a 1 con los datos principales de la tabla. Procuraría tener una tabla con los datos esenciales y sus índices de búsqueda asociados, y otra tabla con los datos no usados en las búsquedas. El mantenimiento de esto es mínimo (añadir y quitar campos) y el movimiento de datos en consultas también.

    Una base de datos no debe saber nada del negocio, es otra opción, pero estás anulando unas potencia de las Base de datos. Si no usamos, vistas, procedimientos almacenados, triggers, etc. Perdemos la potencia de estas Bases de datos. Parece que quieres volver a los ficheros de acceso directo, y crear tú los árboles binarios de búsqueda.

    Cuando tenemos una información opcional es cuando debemos hacer uso de las relaciones 1-1. Al fin y al cabo son extensiones de información de una entidad. Con esas relaciones y la tablas Clave-Valor (diccionarios al fin y al cabo que yo las tengo clasificadas, para en la misma tabla poder tener distintas enumeraciones), se evita mucha complejidad a las B.D.

    Saludos.

  • http://blog.chuidiang.com chuidiang

    Hola:

    Luego nos quejamos de que toda la información interesante está en inglés. Normal si los de habla española nos empeñamos en hacerlo en inglés … ¿por qué motivo?. Decide a qué público va el post, hispano o gente con suficiente nivel de inglés, y escribe en consecuencia. Yo, por ejemplo, no lo habría leído de estar en inglés.

    En cuanto a lo de base de datos, la idea es interesante. Tengo el mismo problema que tú y a veces tiendo a hacer eso, más que nada por la pereza de crear columnas nuevas y modificar tablas. Por cierto, aplicaciones como Openfire (servidor de chat), lo hacen, por ejemplo, los usuarios con permiso de administración se guardan en una tabla “propiedades” con dos columnas, “key” y “valor”. “key” es admin y valor son los nombres de usuario separados por comas. Aparte, un usuario puede en su cliente de chat guardar sus salas de chateo favoritas con cierta información. Todos esos “marcadores” se guardan para cada usuario en un único registro y columna, en un formato que creo recordar es xml.

    Se bueno.

  • http://twitter.com/arbano arbano

    Tenemos algo muy similar y terminas con una tabla que crece muy rápido y es difícil hacer queries sobre la misma. Fué un requerimiento explícito del director quien era ajeno a nuevos frameworks y es algo y que por lo mismo preferimos no utilizar.
    Un buen orm te permite hacer cambios a DB con impacto mínimo en código.
    En nuestros caso no toma más de unos minutos agregar un campo y hacerlo visible en todo el sistema.

  • Alberto

    Buenas,

    el artículo me parece muy interesante por la cantidad de comentarios que ha generado.

    Creo que la BBDD SQL y no-sql tienen sus campos de acción específicos. No obstante, técnicas no-sql pueden resultar últiles en proyectos SQL. Personalmente, casi siempre he trabajado con bases de datos SQL (Oracle y SQL Server), me gusta diseñar la BBDD normalizada, y desnormalizarla para aumentar el rendimiento en casos particulares. Se que es lo contrario de lo que opina Carlos, pero creo que las modificaciones haciendolo así serán menores que haciendolo primero desnormalizado y normalizar después. Evidenmente, es necesario tener claro lo que quiere el cliente, cosa que casi siempre es bastante difícil

    Un saludo, y sigue así Carlos

    Saludos

  • Oskar

    Muy bueno.
    En inglés seguramente no lo habría leido