La importancia del Modelo de Datos

ODM1_1SchemaDiagram_md_582x372

En un artículo publicado en 2004 y titulado “Designing Schemas”, Cameron O’Rourke de Oracle decía una frase para reflexionar: “las aplicaciones van y vienen pero los datos viven para siempre“[1].
Si miramos el horizonte temporal de las aplicaciones en una organización, vemos que esto es una gran verdad. Con el tiempo vendrán aplicaciones nuevas, se automatizarán más procesos, habrá tecnología más eficiente y atractiva, pero los datos se irán migrando desde una aplicación a la siguiente. Habrá registros de clientes que están allí desde los primeros tiempos de la compañía. Por lo tanto es de gran importancia tener un buen modelo de datos. Si contamos con buenos esquemas en las aplicaciones, los datos capturados y almacenados tendrán una estructura que refleja adecuadamente las entidades del mundo real y no se verán expuestos a continuas transformaciones. Cuando un dato relevante no se captura desde el principio y luego se ve la necesidad de añadirlo sobreviene la pregunta de qué hacer con los registros que ya están cargados, ¿qué valor asignarles?

Un buen modelo de datos es el punto de partida en el diseño de una aplicación.  Ya sea que partamos de un diagrama Entidad/Relación o de un Esquema de la base de datos, es el momento en que pensamos en el qué del problema a resolver antes que en el cómo. Quiénes son las entidades, qué atributos esenciales tienen y cómo se relacionan entre sí son las cosas que hay que tener en claro desde el principio, antes de pensar en alguna funcionalidad específica.  Con el tiempo, las necesidades del negocio o el contexto cambian y es necesario extender el modelo, contemplar actores en los procesos que antes no eran relevantes. Si el modelo está bien hecho no habrá problemas en hacerlo evolucionar sin que haya que hacer una reingeniería del modelo entero.

Algunos marcos de trabajo orientados a objetos intentan que el desarrollador modele todo en objetos del lenguaje de programación para que luego el marco genere el esquema en la base de datos gracias al mapeo objeto-relacional (ORM). De este modo intentan aislar al desarrollador de la base de datos. Tratan a lo almacenado en la base de datos como estados de los objetos, lo que les da persistencia, y no como la fuente genuina de los datos.  Hay muchos argumentos en contra de los ORM [2]. En una base de datos relacional se piensa en conjuntos (relaciones o listas). El lenguaje SQL es no procedimental y está orientado a operaciones de conjunto con los datos. Esto no encaja muy bien con el modelo de objetos de entidades. Un esquema bien diseñado desde este punto de vista evitará luego tener que programar complicados procedimientos para realizar una consulta en el lenguaje de programación de la aplicación.

Hay otros marcos de trabajo más orientados a conjuntos y listas que cuentan con herramientas de modelado de más alto nivel permiten definir nuevas entidades y relacionarlas entre sí o con otras existentes según el criterio de cardinalidad de “uno-a-uno”, de “uno-a-muchos”, de “muchos-a-uno” o de “muchos-a-muchos”. La idea está bien, pero muchas veces la implementación del framework consiste en crear tablas de intersección no sólo para el caso “muchos-a-muchos” que es imprescindible en la filosofía relacional, sino también el el caso “uno-a-muchos”, cuando se podría resolver a nivel de la base de datos con claves ajenas e integridad referencial. Si una consulta necesita extraer datos de dos tablas con relación “uno-a-muchos” , en una base de datos con un esquema bien hecho que use las claves ajenas, requerirá un JOIN de exactamente esas dos tablas. Pero la misma consulta en un esquema generado por uno de estos frameworks necesitará un JOIN de 3 tablas, las dos tablas deseadas más la tabla de intersección. Si consideramos que en una aplicación normal hay decenas o cientos de tablas relacionadas entre sí, nos daremos cuenta de que estos frameworks tendrán un problema de rendimiento ya que cargan mucho más a la base de datos por el estilo de su esquema, al mismo tiempo que el desarrollo de consultas en las que intervienen relaciones más anidadas se complica mucho.

Para optimizar el rendimiento de la base de datos disminuyendo el tráfico por la red, una buena práctica es escribir consultas y operaciones complejas que se utilizan repetidamente como procedimientos almacenados en la base de datos. Así ganamos no sólo en rendimiento sino en consistencia. Si necesitamos extender el esquema de manera que afecte a una de estas consultas tendremos un sólo punto de modificación y habrá menos posibilidades de introducir errores. Está en discusión cuánta lógica es conveniente poner en la base de datos como procedimientos almacenados. Si no dependemos en absoluto de ellos, la aplicación será menos dependiente de una base de datos en particular ya que en general hay poca compatibilidad en los procedimientos almacenados de diferentes motores de bases de datos. Pero habremos perdido mucha de la potencia brindada por la base de datos. Por el otro lado, intentar resolver demasiados problemas procedimentales con el lenguaje de los procedimientos almacenados nos lleva a hacer las cosas menos eficientemente porque no hay tantas librerías y los recursos en estos lenguajes son mucho más limitados.

Hay muchos factores que deben tenerse en cuenta en el diseño de un buen modelo de datos, tarea que tiene algo de ingeniería, algo de arte y hasta algo de psicología.  Podemos destacar algunos de estos principios, que más de una vez olvidamos aplicar.

  • Intentar comprender muy bien el dominio del problema, los requerimientos y lo que los usuarios dicen necesitar. Esto contiene la parte psicológica del análisis.
  • Usar reglas de estilo coherentes para los nombres de las tablas, columnas, restricciones (constraints), vistas y demás objetos de la base de datos.
  • Seguir las prácticas de normalización para tener un esquema limpio, sin compromisos. La normalización a distintos niveles fue abordada en el artículo clásico de William Kent [3].
  • Utilizar todos los mecanismos posibles de integridad de la base de datos (NOT NULL, FOREIGN KEY, CHECK ).
  • Usar definiciones de dominios para las listas de valores.
  • Usar claves subrogadas (GUIDs o secuencias) sólo cuando no se puedan identificar atributos estables de la entidad que constituyen la clave única (clave natural) o cuando el uso de éstos es demasiado costoso en términos de rendimiento. Louis Davidson hace una interesante discusión acerca de este controvertido tema [4].
  • Considerar el ciclo de vida completo de las entidades. Este es un error frecuente que se encuentra en las aplicaciones. Muchas veces faltan tablas históricas que permitan la trazabilidad y el análisis de períodos anteriores. Otras veces no se pueden eliminar o pasar a históricos registros dados de baja por las relaciones que tienen. Aquí algo de desnormalización puede ser necesario.
  • Definir cuidosamente las acciones en cascada (como ON DELETE CASCADE).

Hay muchos factores opinables y el arte del diseño consiste en armonizar criterios para brindar un modelo sólido, consistente, elegante y que satisfaga los requerimientos del problema en el presente, pero que también soporte bien la evolución del sistema en le futuro.

Referencias

[1] Designing Schemas (Cameron O’Rourke – Oracle Magazine Jan/Feb 2004)
[2] Arguments against using an ORM layer – an ammunition stockpile [Corey Trager]
[3] A Simple Guide to Five Normal Forms in Relational Database Theory [William Kent]
[4] Ten Common Database Design Mistakes [Louis Davidson]

 

One thought on “La importancia del Modelo de Datos

  1. Pingback: En los datos, la calidad importa | Liberix Information Technologies