Patrones de diseño multidimensional

El primer diseño de un datamart siempre es duro. Uno no tiene muy claro por qué tipo de esquema relacional se debe decantar, qué elementos deben constituir las dimensiones, cuales son los hechos objetivo de análisis… da igual que partamos de un sistema OLTP ya existente, o que estemos partiendo de la nada: son decisiones que todo analista tiene que tomar, y son decisiones que ahora mismo las están tomando miles de cerebros mientras yo escribo estas líneas. Vaya… problemas similares… decisiones que se toman una y otra vez… ¿eso suena a patrones, no?

No hay muchos patrones relacionados con el mundo del "business intelligence", pero por suerte, esta situación empieza a mejorar a rápidamente.

Los Dimensional Design Patterns (DDP)

Este es un conjunto de patrones que nos ayuda a identificar las dimensiones de un cubo OLAP, así como los atributos asociados a cada miembro de la dimensión. Son muy útiles, sobre todo cuando empezamos. Para el que ya tenga algún diseño a su espalda, estoy seguro de que le servirán para emparejar todas las dimensiones que haya diseñado con un patrón existente. Éstos patrones están aún en pleno desarrollo, pero sus creadores ya han publicado un artículo en la revista de la ACM en la que exponen su investigación. A mi personalmente me han parecido muy útiles. Los podéis leer en el siguiente artículo:  

 

Dimensional modeling: identifying, classifying & applying patterns

Full text

pdf formatPdf (289 KB)

Source

Data Warehousing and OLAP archive
Proceedings of the 8th ACM international workshop on Data warehousing and OLAP table of contents

Bremen, Germany
SESSION: Data warehouse models table of contents
Pages: 29 – 38  
Year of Publication: 2005
ISBN:1-59593-162-7

Authors

Mary Elizabeth Jones  Drexel University, Philadelphia, PA
Il-Yeol Song  Drexel University, Philadelphia, PA

 

La literatura de "Project REAL" (Microsoft)

Otra joya de Internet es el llamado "Project REAL". No son patrones en sí mismos, o al menos no están escritos como tales… pero sí que son documentos que explican decisiones tomadas y lecciones aprendidas durante un proyecto real, realizado por Microsoft para Barnes & Noble. Podéis encontrar toda esta información en: http://www.microsoft.com/sql/solutions/bi/projectreal.mspx.

Ya se que no es mucho pero…

El mundo está esperando que compartas tus patrones de Business Intelligence. Yo sólo conozco estas dos direcciones de interés, pero… ¿por qué no escribes un comentario, o me dejas un mensaje con los enlaces a tus patrones favoritos? ¡Prometo recopilarlos, revisarlos y subirlos a geeks!

¡Felices búsquedas!

¿Estrella o copo de nieve?

A todos nos ha pasado: empezamos un nuevo proyecto y nos enfrentamos al diseño de un nuevo datamart… es importante hacerlo bien, porque será la base para nuestros cubos OLAP. ¿Debemos diseñar el almacenamiento relacional subyacente en estrella, o en copo de nieve? Lo cierto es que sobre este tema han corrido ríos de tinta, y sin embargo parece que aún hay discusiones. ¿Cual es la elección correcta?

Una variable multidimensional, dos bases de datos

Lo primero para decantarse por uno u otro diseño es tener bien claro cómo se almacena una variable multidimensional. La mejor forma de comprender la naturaleza de una variable multidimensional es compararlo con un sistema cartesiano.

  • Las dimensiones, son los ejes del sistema.
  • Los hechos, son los "puntos" que vamos a ubicar en esos ejes.
  • Estos "puntos" deben colocarse en coordenadas enteras dentro de los ejes cartesianos: jamás en coordenadas que se representen por medio de fracciones. Como muchos de los "puntos" que queremos representar contienen "fracciones" en sus coordenadas, tenemos que agregarlos para llegar a representarlos en el sistema. Tanto estos "puntos", como los distintos valores que puede tomar una coordenada, se cargan de una base de datos relacional (el datamart).
  • Las dimensiones de una variable multidimensional tienen "niveles". Para cada nivel sucesivo, las coordenadas cartesianas de esa dimensión se "espacian", de forma que los puntos a representar deben establecerse en un sistema "menos preciso". Por lo tanto, es necesario volver a agregarlos.

Por lo tanto, el espacio ocupado por un volumen multidimensional viene condicionado por:

  • Los hechos (puntos) que queremos representar.
  • El número de dimensiones de ese "volumen cartesiano" (los más puristas me diréis que no es un "volumen", sino un sistema… pero bueno, si nos ponemos puristas tampoco hablaríamos de cubos, sino de hipercubos, ¿no?)
  • El número de distintos valores que puede tomar cada dimensión (cómo de "espaciada" esté la componente cartesiana que sitúa un punto en esa dimensión).
  • El número de niveles de una dimensión, considerando a su vez la colección de posibles valores de ese nuevo nivel.

Los metadatos que dan la forma al cubo, y los agregados que constituyen el conjunto de puntos representado sobre el sistema cartesiano se almacenan en un volumen de datos multidimensional (por ejemplo, lo que sería la base de datos de Analysis Services). Los hechos que queremos agregar en el espacio multidimensional y los valores que pueden adoptar cada una de las coordenadas del sistema cartesiano, se cargan de una base de datos relacional (el datamart, que iría soportado, por ejemplo, sobre SQL Server).

Para aquellos a los que os queden dudas acerca de cómo se representa una variable multidimensional, os recuerdo que leáis el artículo de mi amigo y excelente divulgador Manuel de la Herran "Cómo diseñar grandes variables en bases de datos multidimensionales" (http://www.redcientifica.com/doc/doc200104190004.html).

Bien, ahora ya podemos empezar a entender las razones para adaptar un diseño en estrella o en copo de nieve.

La belleza de lo simple

Todo diseñador novel que se precie, y que venga del mundo relacional, tendrá una tendencia "natural" a normalizar… y aunque nos parezca mentira, lo más normal es al estudiar lo que será una dimensión, nos salga normalizada. Generalmente, por cada nivel de una dimensión, nos saldrá una tabla en el modelo relacional. Sin embargo, aunque el diseño más fácil de entender para un desarrollador sea el de un conjunto de dimensiones normalizadas (copo de nieve), fijaros en cómo trabaja un analista de negocio sobre Excel… EXACTO: no normaliza en exceso. Si está separando hombres de mujeres en una lista, escribe "Hombre" y "Mujer" al lado de cada nombre: no escribe un 1 o un 2, y pone una nota a pie de página que dice "Leyenda: ver tabla de codificación del género". Los modelos normalizados son fáciles de entender para las máquinas, pero difíciles de leer para el hombre. He aquí la primera razón para no normalizar las dimensiones: una estrella es mucho más fácil de comprender y manejar que un copo de nieve.

Unos cuantos tópicos sobre las estrellas y los copos de nieve

En general, si uno busca por Internet, las razones que esgrimen los defensores de cada uno de los diseños, son las siguientes:

  • El modelo en copo de nieve requiere menos espacio de almacenamiento. Esto es falso casi en todos los casos. Si nos fijamos en el conjunto de agregados de una variable multidimensional (el volumen del que os he hablado al comienzo del post) veremos que el número de valores disitintos que adopta una dimensión, así como el número de niveles de la misma, ES INDEPENDIENTE del DISEÑO relacional subyacente. Tenemos el mismo número de niveles y tenemos el mismo número de valores posibles para las coordenadas en esa dimensión, con lo que el espacio del volumen multidimensional ES EL MISMO. Bien, ¿entonces por qué he insinuado que esta frase es correcta para algunos casos? Aunque el volumen multidimensional de espacio que consumirá esa dimensión es el mismo, no es el mismo el espacio RELACIONAL que consumirá la dimensión en el datamart desde la que se carga. Si tenemos dimensiones EXTREMADAMENTE GRANDES, y en la que muchos atributos de la dimensión se encuentran repetidos o son nulos para determinados tipos de valores, al normalizar esta dimensión, ganaremos espacio en el datamart (recordemos que el datamart es una proyección bidimensional del espacio multidimensional, no el espacio multidimensional en sí). Por lo tanto, se puede ganar espacio al normalizar una dimensión, pero ganaremos espacio en el volumen relacional desde el que se carga el cubo, no en el cubo en sí. Para profundizar en este aspecto, os recomiendo que leáis el artículo "A trio of interesting snowflakes", de Ralph Kimball (http://www.intelligententerprise.com/010629/warehouse1_1.jhtml)
  • El diseño en estrella es más rápido: Esta frase hay que saber comprenderla. La velocidad de consulta del cubo no depende del diseño relacional de la dimensión, porque el motor multidimensional estructura los datos con respecto a dimensiones, no con respecto a las tablas que representan una dimensión. Cuando se "puebla" una dimensión, se leen los posibles valores que podrá tener una coordenada con respecto a esa dimensión, y se generan los correspondientes niveles. Evidentemente, durante este proceso, si la proyección relacional de la dimensión está normalizada, habrá que realizar tantas joins como tablas contenga la dimensión para ir poblando los distintos niveles de la dimensión. Hacer Joins es lento, y por eso se dice que el modelo en estrella es más rápido… pero OJO, SÓLO ES MÁS RÁPIDO DURANTE EL PROCESO DE CARGA DE LA DIMENSIÓN. Si nuestra dimensión es estática y jamás necesita ser regenerada, no se ahorra nada de tiempo. Cuidado con esto, porque podemos obsesionarnos con llegar a un modelo en estrella, y no darnos cuenta de que estamos complicando en exceso el ETL que "desnormaliza" los datos para llegar a este diseño en estrella… y recordad que el ETL se ejecuta sobre la base de datos OLTP, así que debería mantenerse tan eficiente como fuese posible. Para seguir profundizando sobre este tema, os recomiendo que leáis el epígrafe “Eliminate Joins between Fact and Dimension Tables” en la guía de optimización de Analysis Services (http://www.microsoft.com/technet/prodtechnol/sql/2000/maintain/ansvcspg.mspx)

Tanto hablar para no decir nada…

Efectivamente, todavía no me he decantado por ninguno de los dos diseños, y como inteligentemente habráis podido deducir, no me voy a decantar por ninguno. Hay que saber elegir inteligentemente dependiendo de la circunstancia. Habrá que valorar en cada caso:

  • Acceso al almacenamiento relacional subyacente. ¿Habrá aplicaciones o usuarios que accedan directamente al Datamart, sin hacer uso de la capa OLAP? En este caso, sin duda debemos decantarnos por una estrella. No sólo por la simplicidad, sino porque sacar cualquier informe relacional a partir de una estrella, requiere una única JOIN. Si el acceso siempre se realizará a través de una capa OLAP, nos da igual que el diseño sea en estrella o copo de nieve.
  • ¿Cómo son las dimensiones? Si son muy grandes, tienden a cambiar poco, y tienen atributos de gran tamaño y muy repetidos, tal vez interese considerar el espacio que ahorraríamos en el almacenamiento relacional usando un diseño en estrella.
  • ¿Complicamos mucho el ETL para transformar los datos en una estrella? Tal vez interese el diseño en estrella, porque de esta forma la carga de las dimensiones supondrá un esfuerzo para el sistema que soporta el datamart, pero descargaremos de trabajo a la base de datos de la que cargamos al propio datamart (recordemos que aunque el procesamiento sobre el datamart pueda ser incluso más lento, no afectará a los sistemas OLTP de la empresa).

Por último, los que usamos Analysis Services 2005 estamos de enhorabuena, porque al parecer, con esta maravilla de base de datos, el diseño en estrella apenas impacta en el rendimiento… bueno, eso al menos es lo que dicen en los blogs de MSDN (http://blogs.msdn.com/bi_systems/articles/164525.aspx).

A ver si con esto os animáis a mandarme comentarios… ¡que sería la primera vez que este tema no levanta polémica!

Optimizar la transformación Sort en SSIS

Uno de las tareas habituales a realizar con SSIS, suele ser la fusión de tablas que hubiesen sido particionadas horizontalmente en una única tabla. No estoy hablando de desnormalización, sino de los típicos casos en los que nos encontramos con una base de datos OLTP en la que por ejemplo, las transacciones comerciales de cada año han sido fraccionadas en diversas tablas. Para unir estos fragmentos, tenemos la transformación "Merge". El problema de la "Merge", es que requiere que ambas fuentes de datos se encuentren ordenadas con respecto a la misma clave. Aquí es donde surge la tentación de usar previamente la transformación Sort para ordenar estas fuentes.

¿Qué tiene de malo el uso de la Sort en estos casos? La Sort realiza la ordenación de los datos en la memoria del equipo que ejecuta SSIS… y esto puede ser bueno, o malo, según sea el origen de los datos. Supongamos que partimos de dos archivos de texto que contienen los datos desordenados… evidentemente, la Sort es una excelente opción en estos casos, ya que nos ordenará eficientemente los archivos (eso sí, a costa de un elevado consumo de memoria en el equipo que ejecuta SSIS). Sin embargo, ¿qué pasa si los datos vienen de tablas en una base de datos relacional? Alguno pensará que resulta un poco ridículo ordenar los datos en memoria, ¡cuando con una sentencia ORDER BY de SQL ya podemos traernos los datos ordenados! Quien haya pensado eso, está en lo cierto. Sin embargo, aunque traigamos los datos ya ordenados, la sentencia Merge se empeña en repetirnos una y otra vez que debemos usar la Sort. ¿Cómo podemos resolver este desaguisado?

Atentos a este truco del almendruco:

  1. Lo primero es traerse los datos ya ordenados de la base de datos. Para eso, recordad que cuando partimos de una fuente OLEDB, nunca es conveniente leer directamente de una tabla. Siempre es preferible utilizar una sentencia SQL en la que:
    • Nos traigamos únicamente los datos que necesitamos. Esto significa que sólo debemos traer a SSIS las columnas necesarias y la partición horizontal que necesitemos (si tenemos en una tabla las tallas de zapatos de nuestros futbolistas favoritos, y queremos obtener la lista de jugadores que calzan un número mayor que 42, haremos "SELECT DNI, Nombre, Apellidos, TallaZapato FROM Jugadores2003 WHERE TallaZapato > 42", NUNCA nos traeremos la tabla Jugadores completa). Esto hará que se reduzca el ancho de banda necesario para traernos los datos, y que al procesar menor volumen de datos en SSIS, éste pueda aprovechar de una forma más eficiente los buffers.
    • Usaremos la ORDER BY de SQL para ordenar los datos: "SELECT DNI, Nombre, Apellidos, TallaZapato FROM Jugadores2003 WHERE TallaZapato > 42 ORDER BY DNI". Por supuesto, ¡convendría que los datos estuviesen indexados en la base de datos con respecto a ese criterio!
    • Haremos lo mismo con el resto de tablas que queramos fusionar (en nuestro ejemplo, la tabla Jugadores2004).
  2. Aquí es donde empieza la parte interesante: haremos click con el botón derecho en las fuentes de datos, y seleccionaremos "Advanced options". En el nuevo diálogo que nos sale,  seleccionaremos "Input and output properties". En el árbol correspondiente, seleccionamos la salida estándar del nodo (Source Output). En el nodo principal de la salida, editamos la propiedad "IsSorted", y la ponemos a "true".
  3. Sin salir del diálogo de opciones avanzadas, seleccionamos la columna por la que hemos ordenqado el flujo (DNI) y alteramos la propiedad "SortKeyPosition". En esta propiedad debemos indicar qué posición ocupa la columna en la jerarquía de columnas que ordenan el flujo. En nuestro caso, el flujo está ordenado con respecto a un único criterio, así que la clave de esta columna sería "1".

Siguiendo estos pasos, ya podremos eliminar las transformaciones Sort, con lo que liberaremos una gran cantidad de memoria que bién nos vendrá para ejecutar otras tareas del ETL.

El inconveniente de este método está en que la SORT también nos permite eliminar registros duplicados, cosa que no podemos hacer de con este método que os he descrito. Es una pena que Microsoft no nos haya dado un transformación que elimine duplicados en un flujo de datos ordenado… sin embargo, esto es muy fácil de solucionar con un script. Para eso, tras la Merge podemos poner un script que compruebe la clave del registro actual con la del registro anterior, y desvíe los registros duplicados a la salida de errores (o simplemente añada al flujo un valor booleano, indicando si el registro está duplicado.

¡Felices transformaciones!

El XMLA es tu amigo

Sin entrar en discusiones filosóficas acerca de por qué el mundo OLAP no tiene interfaces estandarizadas, lo cierto es que quien da sus primeros pasos en este mundillo se encuentra con que los cimientos sobre los que se construyen las aplicaciones que atacan bases de datos relacionales, son unos débiles ladrillos de adobe en el mundo multidimensional.


¿Qué interfaz debe usar mi aplicación? ¿Cuales existen? ¿Para qué sirven?. Existen sobre todo dos grandes familias de tipos de acceso a bases de datos multidimensionales: aquellos que son interfaces relacionales con alguna extensión que los hace multidimensionales, y los que son puramente multidimensionales. El abanico de posibles mecanismos de conexión depende mucho de la base de datos que se utilice.


Practicamente todas las bases de datos multidimensionales permiten la conexión a través de interfaces relacionales. Las hay muy orientadas al mundo JAVA, que usan jdbc como estándar de conexión y SQL como lenguaje de query (por ejemplo Oracle), y las hay que ofrecen conexiones OLEDB u ODBC.


Acceder a un almacén multidimensional por medio de un API relacional siempre es un problema, porque sólo podremos acceder de esta forma a proyecciones bidimensionales de nuestra base de datos. Esto no significa que no podamos consultar datos estructurados en más de dos dimensiones… sólo significa que cuando los consultemos, al igual que al dibujar un cubo en una pizarra obtenemos una proyección plana, al consultar más de dos dimensiones también obtendremos una proyección aplanada (el resultado de realizar una multiplicación cartesiana de las distintas dimensiones que queremos representar).


Al final, en la interfaz de usuario sólo podemos mostrar dos dimensiones, así que uno podría pensar… qué rayos, me da lo mismo trabajar sobre un conjunto de datos aplanado. ¡No, no, y no! ¡Al aplanar un conjunto de datos multidimensional, hemos perdido gran parte de los metadatos que lo acompañan! Un volumen multidimensional que haya perdido su estructura, no nos permitirá realizar con comodidad operaciones de rotación o pivotado, así que precisamente estamos limitando en gran medida la capacidad de análisis que debería tener el usuario sobre esos datos. Vamos, que cualquier API que sólo permita acceder por medio de una interfaz relacional a un volumen multidimensional, no es más que una chapucilla para salir del paso.


Entonces, ¿qué alternativas nos quedan?


Muchos fabricantes tienen sus propias APIs no estándar que permiten acceder a conjuntos de datos multidimensionales… pero por suerte, también nos encontramos estándares.



  • Algunos estándares se utilizan para acceder a volúmenes multidimensionales utilizando un modelo de objetos. Seguro que podéis haceros una idea, ¿verdad? Instancio un cubo, me voy a la colección de dimensiones, ejecuto ciertas operaciones y me traigo un subconjunto del cubo con los datos que quiero. Oracle apuesta por este tipo de acceso, y como Oracle, todos aquellos que apuestan por JOLAP (http://jcp.org/en/jsr/detail?id=069). Yo veo un problema a este tipo de interfaces, y es que generalmente están ligados a que se desarrolle un determinado modelo de objetos (generalmente complejo) implantado en el lenguaje desde el que se lanzan las queries. Generalmente se desarrollan para un único lenguaje (en el caso de JOLAP es Java), aunque lo cierto es que desde que existen los servicios web, no tendría por qué ser así… ¿no creeis?.
    Microsoft también tiene una API de este tipo: la AMO (Analysis Management Objects), con la particularidad de que AMO sólo sirve para consultar los metadatos de una base de datos OLAP, y nunca para acceder a los datos en sí.
  • Microsoft lanzó en su día ODBO: OLE DB for OLAP. ODBO era una interfaz diseñada casi a medida de Excel, cuyo objetivo era permitir la conexión entre las «Pivot table» de excel y SQL Server Analysis Services. De hecho, a este proveedor OLE DB, se le llamaba también «Microsoft Pivot Table Services». Sin embargo, ODBO empezó a utilizarse para otros fines (por ejemplo, SAP incorpora una interfaz ODBO). Junto con ODBO, Microsoft lanzó un lenguaje de query para bases de datos multidimensionales: el MDX. ODBO transmite los datos en formato binario, a través de sockets TCP o encapsulado dentro de HTTP, pero siempre en formato binario. La pega que se le achacaba en su día a ODBO es el no ser lo suficientemente abierto.
  • En medio de esta guerra, surgió el XMLA como iniciativa de Microsoft. XMLA es un estándar abierto, basado en SOAP. XMLA ha sido rápidamente adoptado por un gran número de fabricantes de bases de datos multidimensionales (Hyperion, SAS, Mondrian…) salvo por Oracle, que lo tacha de estándar propietario de Microsoft. Podéis encontrar información sobre XMLA en www.xmla.org

¿Y por qué es XMLA nuestro amigo? Realmente el XMLA es el único estándar universal del que disponemos. XMLA no excluye a nadie, y puede ser implementado en cualquier lenguaje del mundo que permita programar y consumir web services. Microsoft, Hyperion y SAS ya tienen soporte XMLA, e incluso el mundo open source se está acercando a este estándar. En el mundo .NET, el cliente ADOMD.NET o incluso OLEDB for OLAP 9.0 son clientes XMLA, lo que les permite ir más allá de ser simples interfaces para acceder a Analysis Services y permitirles acceder en teoría a cualquier servidor XMLA (esto no siempre es así, pero no porque ADOMD.NET sea un cliente cerrado, sino porque muchas veces el soporte XMLA de las bases de datos no es lo suficientemente completo).


¿Qué razones hay para no apostar por el XMLA? La única razón es Oracle. Nos dicen que únicamente soportarán JOLAP, y que XMLA es un estándar cerrado de Microsoft. Es curioso que digan esto, ¡porque JOLAP y XMLA no son comparables! JOLAP y AMO sí que serían comparables, pero XMLA es un estándar que define la comunicación con la base de datos multidimensional a un nivel mucho más bajo que JOLAP. De hecho, JOLAP es un API, y XMLA es la definición de una interfaz orientada a servicios. JOLAP podría funcionar perfectamente sobre XMLA, utilizando un api en JAVA para lanzar consultas que se convirtiesen en llamadas «execute» de XMLA con sentencias MDX encapsuladas… bueno, esto no hace falta que lo diga yo, ¡es como actualmente funciona Hyperion!


Así que en esta película, si no nos queda más remedio que programar para Oracle, no nos quedará más remedio que rechazar el XMLA… pero hasta en este último caso, piensa que no hay ninguna razón para enemistarse con el XMLA. Es sólo que a veces las presiones y el politiqueo nos impiden elegir a nuestros amigos ;-).

No habrá versión 2007 de los Office Web Controls

A pesar de que voy un poco tarde con la noticia, allá va el bombazo del verano: Microsoft no sacará versión del 2007 de los Office Web Controls. No os perdáis el post y los comentarios del 17 de julio en el blog de excel 2007: http://blogs.msdn.com/excel/archive/2006/07/17/668544.aspx


Lo cierto del caso es que los OWC eran la alternativa más económica pra construir aplicaciones cliente de cubos OLAP, ya que permitían analizar datos de forma interactiva a cualquier usuario con licencia de Office, y más aún, permitían a los usuarios sin licencia de Office acceder a informes estáticos. Como alternativas, nos queda el desarrollo de aplicaciones basadas en Excel con las Visual Studio Tools for Office, o tal y como se propone en el blog, Microsoft Office SharePoint Server 2007. Bueno, u otras alternativas más caras como Scorecard Manager o los productos que ha adquirido Microsoft tras la compra de ProClarity en mayo.