Cualquiera que haya entrado recientemente al mundo del Business Intelligence sabe que, tras superar la fase de la extracción de datos (ETL), llegas al verdadero campo de batalla: el modelado dimensional. Hemos empezado a montar cubos OLAP multidimensionales utilizando SQL Server Analysis Services (SSAS) sobre SQL Server 2008 R2, y las discusiones sobre cómo estructurar las bases de datos están siendo épicas.
El debate se reduce a la eterna pelea entre dos filosofías de diseño: el Esquema en Estrella (Star Schema), propuesto por Ralph Kimball, contra el Esquema en Copo de Nieve (Snowflake Schema).
La teoría detrás del debate
En un Data Warehouse, tenemos la "Tabla de Hechos" (las métricas o transacciones, como las ventas) rodeada de "Dimensiones" (el contexto: tiempo, clientes, productos).
En el Copo de Nieve, las dimensiones están normalizadas. Si tenemos una dimensión "Producto", ésta se enlaza a una tabla "Subcategoría", que a su vez se enlaza a "Categoría". Es lo que nos enseñaron en la universidad para evitar la redundancia de datos.
En el Esquema en Estrella, rompemos las reglas puristas: desnormalizamos las dimensiones. Toda la jerarquía de Categoría, Subcategoría y Producto se aplasta en una única y enorme tabla Dim_Producto.
Al principio, mi cerebro de desarrollador de bases de datos transaccionales se resistía al esquema en estrella. "¡Estamos repitiendo el nombre de la categoría mil veces, es un desperdicio de espacio!", le gritaba a mi compañero. Pero luego lo puse en práctica.
El barro técnico: Rendimiento vs Almacenamiento
El motor relacional que alimenta el cubo SSAS (Data Source View) sufre terriblemente cuando tiene que resolver múltiples JOINs masivos. Veamos la diferencia en código SQL a la hora de procesar o consultar el cubo.
Consulta típica en Copo de Nieve:
SELECT
c.NombreCategoria,
SUM(f.ImporteVenta) AS TotalVentas
FROM Fact_Ventas f
JOIN Dim_Producto p ON f.IdProducto = p.IdProducto
JOIN Dim_SubCategoria sc ON p.IdSubCategoria = sc.IdSubCategoria
JOIN Dim_Categoria c ON sc.IdCategoria = c.IdCategoria
GROUP BY c.NombreCategoria;
Consulta equivalente en Esquema en Estrella:
SELECT
p.NombreCategoria,
SUM(f.ImporteVenta) AS TotalVentas
FROM Fact_Ventas f
JOIN Dim_Producto p ON f.IdProducto = p.IdProducto
GROUP BY p.NombreCategoria;
La diferencia a nivel de motor de base de datos es abismal. SSAS digiere los esquemas en estrella muchísimo más rápido durante el procesamiento del cubo porque se ahorra saltar por tres tablas distintas. Y lo más importante: cuando diseñas el cubo en Visual Studio (BIDS), mapear las jerarquías desde una sola tabla es un paseo, mientras que con el copo de nieve te expones a problemas de granularidad y relaciones complejas.
Reflexión: La normalización está sobrevalorada en BI
He tenido que admitir mi derrota en este debate. Los discos duros son ridículamente baratos. Preocuparse por ahorrar 50 Megabytes desnormalizando cadenas de texto en una tabla de dimensiones es absurdo cuando el verdadero cuello de botella es el rendimiento de la CPU al procesar los JOINs.
El Esquema en Estrella se ha convertido en mi estándar de facto. Sin embargo, SSAS es un monstruo pesado basado en disco (MOLAP). He estado leyendo sobre las nuevas tecnologías "In-Memory" que Microsoft está preparando (como el motor VertiPaq o BISM). Si en el futuro podemos cargar todo el modelo analítico directamente en la memoria RAM, me pregunto si este debate entre estrella y copo de nieve dejará de tener sentido. Quizás la fuerza bruta de la memoria venza al diseño del modelo, pero por ahora, Kimball manda.