lección 3
El esquema estrella: diseñando tu primera estructura analítica
Construye un esquema estrella completo con una fact table central y dimensiones conectadas. El patrón más usado en Data Warehousing.
⏱ 55 min
Ya sabes qué son hechos y dimensiones. Ahora vamos a juntarlos en un patrón formal: el esquema estrella (star schema). Se llama así porque cuando lo dibujas en un diagrama ER, parece una estrella: la tabla de hechos en el centro y las dimensiones irradiando como puntas. Es el patrón más usado en Data Warehousing desde que Kimball lo popularizó en los 90, y sigue siendo el estándar en 2024.
La belleza del esquema estrella es su simplicidad para el usuario final. Un analista de negocio que sepa SQL básico puede escribir queries efectivas porque la estructura refleja cómo piensa sobre los datos: "dame las ventas (hecho) por categoría de producto (dimensión) y mes (dimensión) para clientes VIP (dimensión)". Cada pregunta de negocio se traduce directamente a un SELECT + JOINs contra la estrella.
### Reglas del esquema estrella
- 01.UNA tabla de hechos en el centro — representa el proceso de negocio que mides
- 02.Dimensiones alrededor — cada una conectada a la fact table por UNA foreign key
- 03.Las dimensiones NO se conectan entre sí — solo a la fact table (esto es clave)
- 04.La fact table contiene SOLO claves ajenas y métricas numéricas — ni un atributo descriptivo
- 05.Las dimensiones son desnormalizadas (no hay tablas puente entre dimensiones)
- 06.Cada dimensión tiene una surrogate key como PK
- 07.Un esquema estrella = un proceso de negocio. Si tienes ventas Y envíos, son dos estrellas
### Ejemplo completo: estrella de ventas de un e-commerce
Vamos a diseñar paso a paso la estrella para el proceso "una línea de venta". El negocio quiere responder preguntas como: ventas por categoría, por mes, por región, por canal de adquisición, evolución de nuevos vs recurrentes, ticket medio por día de la semana, etc.
1-- ═══════════════════════════════════════════════════════2-- ESQUEMA ESTRELLA: Ventas de e-commerce3-- ═══════════════════════════════════════════════════════45-- ─── DIMENSIONES ──────────────────────────────────────67CREATE TABLE dim_date (8 date_key INTEGER PRIMARY KEY,9 full_date DATE NOT NULL UNIQUE,10 day_name VARCHAR(10),11 month_name VARCHAR(10),12 month_number SMALLINT,13 quarter SMALLINT,14 year SMALLINT,15 is_weekend BOOLEAN,16 is_holiday BOOLEAN17);1819CREATE TABLE dim_customer (20 customer_key BIGINT PRIMARY KEY,21 customer_id VARCHAR(20),22 full_name VARCHAR(200),23 email VARCHAR(200),24 country VARCHAR(50),25 city VARCHAR(100),26 segment VARCHAR(30),27 acquisition_channel VARCHAR(30),28 first_order_date DATE29);3031CREATE TABLE dim_product (32 product_key BIGINT PRIMARY KEY,33 product_id VARCHAR(20),34 product_name VARCHAR(200),35 category VARCHAR(50),36 subcategory VARCHAR(50),37 brand VARCHAR(100),38 unit_cost DECIMAL(10,2),39 is_active BOOLEAN40);4142CREATE TABLE dim_store (43 store_key BIGINT PRIMARY KEY,44 store_id VARCHAR(10),45 store_name VARCHAR(100),46 city VARCHAR(100),47 region VARCHAR(50),48 country VARCHAR(50),49 store_type VARCHAR(20), -- 'online', 'physical'50 open_date DATE51);5253-- ─── TABLA DE HECHOS ──────────────────────────────────5455CREATE TABLE fact_sales (56 -- Surrogate key del hecho (opcional pero útil)57 sales_key BIGINT PRIMARY KEY,58 -- Foreign keys a dimensiones59 date_key INTEGER NOT NULL REFERENCES dim_date(date_key),60 customer_key INTEGER NOT NULL REFERENCES dim_customer(customer_key),61 product_key INTEGER NOT NULL REFERENCES dim_product(product_key),62 store_key INTEGER NOT NULL REFERENCES dim_store(store_key),63 -- Dimensión degenerada (no tiene su propia tabla)64 order_number VARCHAR(20),65 -- Métricas66 quantity SMALLINT NOT NULL,67 unit_price DECIMAL(10,2) NOT NULL,68 discount_pct DECIMAL(5,2) DEFAULT 0,69 net_amount DECIMAL(12,2) NOT NULL, -- quantity * unit_price * (1-discount)70 tax_amount DECIMAL(10,2),71 shipping_cost DECIMAL(10,2)72);
Esquema estrella completo. 4 dimensiones + 1 fact table + 1 dimensión degenerada (order_number).
Nota sobre dialecto: el DDL de arriba usa SERIAL (PostgreSQL) para las surrogate keys. En DuckDB usarías INTEGER PRIMARY KEY con una secuencia o simplemente generarías los IDs en tu ETL. Si copias el código al editor de la plataforma (que usa DuckDB), SERIAL dará error. Esto es intencional: en producción real usarás PostgreSQL, Redshift o BigQuery — no DuckDB — para el warehouse.
### Esquema snowflake: cuando normalizas las dimensiones
Una variante es el esquema copo de nieve (snowflake): en vez de tener todos los atributos en una dimensión plana, normalizas la dimensión. Por ejemplo, en vez de dim_product con category como VARCHAR, creas una tabla separada dim_category y dim_product apunta a ella con un FK. Visualmente, la estrella se convierte en un copo de nieve con ramificaciones.
¿Cuándo usar snowflake? Casi nunca. La normalización ahorra un poco de espacio, pero el espacio en un warehouse es barato. Lo que NO es barato es el rendimiento: cada JOIN adicional es tiempo de ejecución y complejidad para el analista. El consenso de la industria: usa star schema por defecto. Solo normaliza una dimensión si es MUY grande (millones de filas) y la normalización reduce significativamente su tamaño.
Regla de oro que uso en cada proyecto: si la dimensión tiene menos de 1 millón de filas, déjala plana (star). Si tiene más de 10 millones Y un atributo se repite mucho (como país en una tabla de ciudades), considera normalizar ESE atributo. Pero la fact table siempre apunta directamente a las dimensiones principales — nunca hagas que el analista tenga que hacer 3 JOINs para llegar al nombre de la categoría.
### Conformed dimensions: reutilizar entre estrellas
Una empresa no tiene una sola estrella — tiene varias. Ventas, envíos, devoluciones, visitas web, campañas de marketing. ¿Qué pasa si cada estrella tiene su propia dim_customer con definiciones diferentes de "segmento"? Caos. Los números no cuadran entre departamentos.
La solución de Kimball: conformed dimensions. Son dimensiones compartidas entre múltiples fact tables, con la MISMA definición y los MISMOS valores. dim_date es la conformed dimension más obvia — todas las estrellas usan la misma. dim_customer debería ser la misma en ventas, soporte y marketing. Esto es lo que permite hacer queries "cross-process": "clientes que compraron en Q4 Y abrieron un ticket de soporte".
### Errores comunes al diseñar estrellas
- Meter atributos descriptivos en la fact table — si no es sumable/promediable, es dimensión
- Crear dimensiones con pocas filas que deberían ser junk dimensions (flags, estados)
- No incluir dim_date — usar funciones de fecha directamente sobre un timestamp en la fact
- Conectar dimensiones entre sí — viola el principio de la estrella y complica queries
- Mezclar granularidades en la misma fact table (ventas diarias Y mensuales juntas)
- Usar natural keys como FK en la fact table — siempre surrogate keys
El error más costoso que he presenciado: un equipo diseñó su estrella sin conformed dimensions. Marketing tenía su dim_customer, ventas tenía otra, soporte otra. Cuando el CEO preguntó "¿cuántos clientes compraron Y se quejaron?", no se podía responder sin un proyecto de integración de 3 meses. Las conformed dimensions son la FUNDACIÓN — defínelas primero, antes de construir ninguna fact table.
## ejercicios
Diseñar estrella para un servicio de streaming
Netflix quiere analizar reproducciones. Diseña un esquema estrella con fact_playback (cada reproducción) y las dimensiones necesarias para responder: "minutos vistos por género y país, en fin de semana vs laborable, en dispositivo móvil vs TV".
Convertir snowflake a star
Te dan un esquema snowflake donde dim_product está normalizado en 3 tablas (product, category, brand). Reescríbelo como star schema con una sola dim_product plana.
Identificar conformed dimensions
Tu empresa tiene 3 procesos: ventas online, ventas en tienda física, y devoluciones. Lista las dimensiones que deberían ser CONFORMED (compartidas) entre los 3 procesos y explica por qué.
Escribir 3 queries de negocio sobre la estrella
Usando una mini-estrella de e-commerce (fact_sales + dim_date + dim_customer + dim_product), escribe queries para: 1) Revenue mensual, 2) Top 2 categorías por país, 3) Comparación weekend vs weekday. Ejercicio autocontenido: el seed ya está en el editor, solo completas las 3 queries. Ejecútalo en DuckDB.
Regístrate para guardar tu progreso.
## comentarios
Reporta erratas, ayuda a otros o comparte tu opinión. Sé constructivo.
Inicia sesión para comentar y responder.
cargando comentarios...