Módulo 1: From Flat Tables To Dimensional Models
Paso 1: seleccionando el proceso de negocio de Kiosko
Descripción
Con el proceso completo ya claro sobre la cafetería de la lección anterior, esta lección da el primer paso real sobre Kiosko: select the business process. Kiosko tiene, heredados de foundations, dos flujos de datos crudos —orders (el punto de venta) y events (el clickstream de la app, con page_view/add_to_cart/purchase)—, y cada uno podría ser la semilla de un proceso de negocio distinto. Esta lección no elige al azar: compara ambos candidatos con un criterio explícito, y justifica por qué esta guía empieza por orders.
Conexión con el módulo. Esta lección resuelve el paso 1 del proceso de Kimball para fact_orders, la tabla que las lecciones 5 y 6 de este módulo van a terminar de declarar. events no se descarta —vuelve como protagonista del módulo 6, cuando construyas el accumulating snapshot del funnel de sesiones—, solo se pospone con una razón concreta.
Una analogía: el menú del primer día, no el menú completo
Un restaurante nuevo con un chef ambicioso podría, en teoría, abrir con un menú de treinta platillos distintos el primer día. En la práctica, ningún restaurante serio hace eso: abre con dos o tres platillos bien ejecutados, aprende de la operación real —qué se pide más, qué tarda demasiado en cocina, qué ingrediente se agota rápido— y expande el menú después, con la confianza de haber resuelto bien lo primero. Elegir qué platillo sale primero no es una decisión menor: determina qué aprende el restaurante en sus primeras semanas.
Kiosko tiene dos "platillos" candidatos para el primer modelo dimensional de esta guía: las órdenes de venta (orders) y las sesiones de navegación en la app (events). Esta lección elige uno para servir primero, con criterio explícito — no porque el otro no importe, sino porque un modelo dimensional bien construido, aprendido a fondo sobre un proceso, es la base sobre la que se construye el segundo con más velocidad y menos errores.
Ejemplo trabajado: comparando los dos procesos candidatos
Antes de elegir, vale la pena poner los dos candidatos lado a lado, con un criterio explícito para cada uno:
# business_process_candidates.py
CANDIDATES = [
{
"process": "Ordenes de venta (orders)",
"source": "Punto de venta de cada tienda, exportado cada noche",
"data_ready_today": True,
"measurable_event": "Una venta puntual: producto, cantidad, precio, instante",
"already_modeled": "fact_orders, dim_store, dim_product (foundations M4/M8)",
},
{
"process": "Sesiones de navegacion (events)",
"source": "App de delivery, clickstream en tiempo real",
"data_ready_today": False,
"measurable_event": "page_view / add_to_cart / purchase, por sesion",
"already_modeled": "Ninguna tabla de hechos todavia -- solo el formato JSON Lines crudo",
},
]
print("=== Candidatos a proceso de negocio para el primer modelo dimensional ===\n")
for c in CANDIDATES:
print(f"Proceso: {c['process']}")
print(f"Fuente: {c['source']}")
print(f"Dato listo hoy: {c['data_ready_today']}")
print(f"Evento medible: {c['measurable_event']}")
print(f"Ya modelado como: {c['already_modeled']}")
print()
chosen = CANDIDATES[0]
print(f"Proceso elegido para este modulo: {chosen['process']}")
Qué esperar. Al correr python3 business_process_candidates.py, la salida es exactamente esta:
=== Candidatos a proceso de negocio para el primer modelo dimensional ===
Proceso: Ordenes de venta (orders)
Fuente: Punto de venta de cada tienda, exportado cada noche
Dato listo hoy: True
Evento medible: Una venta puntual: producto, cantidad, precio, instante
Ya modelado como: fact_orders, dim_store, dim_product (foundations M4/M8)
Proceso: Sesiones de navegacion (events)
Fuente: App de delivery, clickstream en tiempo real
Dato listo hoy: False
Evento medible: page_view / add_to_cart / purchase, por sesion
Ya modelado como: Ninguna tabla de hechos todavia -- solo el formato JSON Lines crudo
Proceso elegido para este modulo: Ordenes de venta (orders)
La decisión no es "orders es más importante que events" — de hecho, el funnel de conversión que vas a construir sobre events en el módulo 6 es una de las piezas más valiosas de negocio de toda esta guía—. La decisión es de secuencia: orders ya tiene una tabla de hechos construida y verificada (foundations la dejó lista), así que declarar su grano formalmente es el ejercicio más directo posible para aprender el proceso de Kimball por primera vez, sin la complicación adicional de construir una tabla de hechos desde cero al mismo tiempo. events, en cambio, todavía es JSON Lines crudo sin ninguna tabla de hechos encima — construir esa tabla desde cero y aprender a declarar su grano al mismo tiempo sería repetir el error que la lección 3 del módulo 8 de foundations ya advirtió: enseñar dos cosas nuevas a la vez diluye ambas.
Diagrama: dos procesos, dos momentos de esta guía
flowchart TD
subgraph Fuentes["Fuentes de Kiosko (heredadas de foundations)"]
A["orders\n(punto de venta)"]
B["events\n(clickstream de la app)"]
end
A --> C["fact_orders\nYA CONSTRUIDO (foundations)\nsolo falta declarar el grano formalmente"]
B --> D["fact_sessions\nNO construido todavia\n(accumulating snapshot, modulo 6)"]
C --> E["Este modulo (M1): grano de fact_orders"]
D --> F["Modulo 6: proceso de negocio +\ngrano + dimensiones + hechos de fact_sessions\ndesde cero"]
Profundización: por qué "el dato ya existe" no es el único criterio
Es tentador pensar que el criterio para elegir un proceso de negocio es simplemente "¿ya tengo el dato?". Es un criterio real —y en el caso de Kiosko, favorece a orders—, pero no es el único, y vale la pena nombrar los otros dos que el Kimball Group menciona: las necesidades reales del negocio, y qué tan bien entendido está el proceso por el equipo que lo va a modelar.
Sobre las necesidades del negocio: la gerente de Kiosko, en el brief que abrió foundations, pidió específicamente un reporte de ventas —no un reporte de comportamiento de navegación—. Eso, por sí solo, ya inclina la balanza hacia orders como el proceso con mayor urgencia de negocio hoy. Sobre qué tan bien entendido está el proceso: orders es un proceso simple y ya familiar —una venta, un producto, un precio—, mientras que events introduce conceptos nuevos (sesiones, milestones que avanzan sin crear filas nuevas) que merecen su propio módulo completo, en vez de mezclarse apurados aquí.
Ningún criterio, por sí solo, habría sido suficiente. Fue la combinación de los tres —dato disponible, urgencia de negocio, y complejidad conceptual manejable— lo que hizo evidente que orders debía ser el primer proceso de esta guía. La próxima vez que tengas que elegir qué modelar primero en un proyecto real, esos mismos tres criterios —no solo "qué dato tengo a mano"— son los que vale la pena poner sobre la mesa.
Errores comunes
Elegir el proceso más fácil de programar, no el de mayor valor de negocio. Qué pasa: alguien prioriza modelar lo que técnicamente es más simple de construir, sin preguntarse qué necesita el negocio primero. Por qué pasa: es natural, al aprender una técnica nueva, gravitar hacia el ejemplo con menos fricción técnica. Cómo detectarlo: si tu justificación para elegir un proceso de negocio no menciona ninguna necesidad concreta del negocio (como el brief de la gerente de Kiosko), solo facilidad técnica, te falta uno de los tres criterios de esta lección. Cómo corregirlo: como hizo el ejemplo trabajado, compara los candidatos con los tres criterios completos —dato disponible, urgencia de negocio, complejidad manejable— no solo uno.
Descartar events como "sin importancia" en vez de "pospuesto con razón". Qué pasa: alguien concluye, al ver que este módulo elige orders, que el clickstream de la app es un dato secundario o poco valioso para Kiosko. Por qué pasa: es fácil confundir "no se modela primero" con "no importa". Cómo detectarlo: si tu resumen de esta lección dice algo como "events no es tan importante", revisa la sección "Conexión con el módulo" al inicio — events es, explícitamente, el protagonista completo del módulo 6. Cómo corregirlo: recuerda que la secuencia de esta guía es pedagógica, no una jerarquía de importancia de negocio — ambos procesos terminan modelados con el mismo nivel de rigor antes de que la guía cierre.
Intentar modelar los dos procesos en una sola tabla de hechos. Qué pasa: alguien, queriendo "ser eficiente", intenta diseñar una tabla única que capture tanto ventas como eventos de navegación, mezclando dos grano completamente distintos. Por qué pasa: parece más simple tener "una sola tabla grande" que dos tablas separadas. Cómo detectarlo: si tu diseño mezcla columnas de orders (quantity, unit_price) con columnas de events (event_type, session_id) en la misma fila, sin que exista una relación de negocio real entre ambas a ese nivel de detalle, ya perdiste el grano de ambos procesos a la vez. Cómo corregirlo: procesos de negocio distintos —con eventos que ocurren en momentos distintos y a niveles de detalle distintos— casi siempre necesitan tablas de hechos distintas. Vas a construir dos tablas de hechos completamente separadas en esta guía (fact_orders y fact_sessions), y eso es correcto, no un desperdicio.
Ejercicios
Ejercicio 1 — Aplica los tres criterios a un tercer candidato hipotético. Imagina que Kiosko también tuviera un archivo inventory_movements.csv (movimientos de inventario: reposición y merma) — un tercer candidato a proceso de negocio, sin dato aún disponible ni requerido por el brief de la gerente. Usando los tres criterios de esta lección, argumenta en 2-3 frases por qué este candidato quedaría, con toda razón, fuera del alcance de esta guía.
Ver solución
inventory_movements fallaría los tres criterios a la vez: el dato no existe todavía en ningún archivo real de Kiosko (criterio 1), la gerente nunca lo pidió en su brief —su urgencia era el reporte de ventas, no el control de inventario— (criterio 2), y modelarlo bien requeriría entender un proceso de negocio nuevo (reposición, mermas, niveles mínimos de stock) que ningún módulo anterior de la guía preparó (criterio 3). Los tres criterios señalando en la misma dirección son justamente la evidencia que hace fácil, y no arbitraria, la decisión de dejarlo fuera de alcance.
Ejercicio 2 — Argumenta el orden inverso. Alguien propone que esta guía debería haber empezado por events (sesiones de navegación) en vez de orders, porque "el clickstream es el dato más moderno y más parecido a lo que se usa en empresas de tecnología reales". Evalúa ese argumento usando los tres criterios de esta lección: ¿es válido?
Ver solución
El argumento tiene algo de razón —el clickstream sí es un tipo de dato muy común en empresas de tecnología reales—, pero "parecerse a lo que usan empresas modernas" no es ninguno de los tres criterios de esta lección: no resuelve si el dato ya está listo (no lo está — events sigue siendo JSON Lines crudo, sin tabla de hechos), no resuelve la urgencia de negocio (el brief pidió ventas, no comportamiento de navegación), y no resuelve la complejidad manejable (accumulating snapshot es un concepto más avanzado que declarar el grano de una tabla ya construida). "Se parece a lo que usan empresas modernas" es un criterio de moda, no de método — exactamente el tipo de razonamiento que el proceso de Kimball busca reemplazar con criterios explícitos y verificables.
Ejercicio 3 — Declara el proceso de negocio de fact_orders en una frase. Sin mirar el ejemplo trabajado, escribe en una sola frase cuál es el proceso de negocio que vas a modelar en el resto de este módulo, usando el mismo formato que usó la lección 3 para la cafetería ("la venta de una bebida").
Ver solución
Una respuesta razonable: "la venta de un producto en una tienda de Kiosko" — el mismo tipo de evento medible, puntual, que ya modelaste sin saberlo en foundations. Fíjate en que esta frase todavía no dice nada sobre el grano —eso es, precisamente, el paso 2, y la lección 5 lo resuelve con una consulta ejecutada—; el paso 1 solo responde "qué evento de negocio", no "qué representa cada fila".
Resumen y siguiente paso
En esta lección resolviste el paso 1 del proceso de Kimball para Kiosko: comparaste los dos procesos de negocio candidatos —órdenes de venta y sesiones de navegación— con tres criterios explícitos (dato disponible, urgencia de negocio, complejidad manejable), y elegiste la venta de un producto en una tienda de Kiosko como el proceso que este módulo modela primero. events no queda descartado — vuelve, con el mismo rigor, en el módulo 6.
Antes de avanzar deberías poder: nombrar los tres criterios para elegir un proceso de negocio, sin ayuda; explicar por qué "el dato ya existe" no es el único criterio válido; y declarar, en una frase, el proceso de negocio elegido para fact_orders.
Con el proceso de negocio ya elegido, la lección 5 resuelve el paso 2 —declarar el grano— y es la lección central de todo el módulo: vas a ejecutar, de verdad, sobre DuckDB, la consulta que confirma con números qué representa exactamente una fila de fact_orders.
Recursos
- Kimball Group — "Four-Step Dimensional Design Process" — la fuente que enmarca el paso 1 aplicado en esta lección. kimballgroup.com/.../four-4-step-design-process. En inglés.
- Joe Reis & Matt Housley, Fundamentals of Data Engineering (O'Reilly, 2022) — el marco de generación de datos (el capítulo sobre fuentes de datos) que respalda por qué
ordersyeventsson procesos de negocio distintos, con ciclos de vida distintos. oreilly.com/library/view/fundamentals-of-data/9781098108298. En inglés. - JSON Lines — especificación del formato que usa
events.jsonl, el formato crudo que espera su turno hasta el módulo 6. jsonlines.org. En inglés.