lección 1
¿Por qué no podemos analizar directo en la base de la app? OLTP vs OLAP
Descubre por qué las bases de datos transaccionales no sirven para análisis y cómo nació la idea del Data Warehouse.
⏱ 50 min
Antes de empezar, un aviso de cambio de marcha. Hasta la Skill 10 tu trabajo era ESCRIBIR código y que el intérprete o el motor te dijera al instante si funcionaba: ejecutabas, veías el resultado, corregías. A partir de aquí entras en modo DISEÑO. En esta skill vas a decidir cómo se estructuran los datos — qué es un hecho, qué es una dimensión, con qué granularidad, cómo versionar el histórico — y muchas de esas decisiones no tienen un "verde/rojo" automático: el andamio que te sostiene ahora es tu CRITERIO, no el intérprete. No te asustes si algunos ejercicios son de diseño y no de ejecutar: es exactamente la habilidad que se espera de un ingeniero cuando modela un warehouse. Aun así, cuando el ejercicio sea SQL puro y autocontenido, lo podrás ejecutar y ver el resultado como siempre.
Imagina esto: eres el ingeniero de datos de una tienda online que procesa 5.000 pedidos por hora. El director financiero te pide un informe de ventas por categoría de los últimos 12 meses. Tú, inocente, lanzas un SELECT con GROUP BY contra la base de datos de producción. La query tarda 47 segundos. Durante esos 47 segundos, 65 clientes intentaron comprar y vieron un spinner infinito. El equipo de backend te envía un mensaje que no puedo reproducir aquí. ¿Qué salió mal?
Lo que salió mal es que usaste una herramienta diseñada para UN propósito (procesar transacciones rápidas) para OTRO propósito completamente diferente (analizar grandes volúmenes históricos). Es como intentar cortar un árbol con un bisturí: el bisturí es una herramienta excelente, pero no para eso. Esta distinción fundamental —bases transaccionales vs bases analíticas— es el punto de partida de todo el modelado dimensional.
### OLTP: Online Transaction Processing
OLTP es el tipo de base de datos que alimenta tu aplicación. Cada vez que un usuario se registra, compra un producto, actualiza su dirección o cancela un pedido, eso es una transacción. La base OLTP está optimizada para procesar MUCHAS transacciones PEQUEÑAS por segundo. Piensa en ella como la caja registradora de un supermercado: procesa una compra cada pocos segundos, rápido, sin errores, y pasa al siguiente cliente.
- Operaciones: INSERT, UPDATE, DELETE individuales o en lotes pequeños
- Filas afectadas por operación: 1 a 100 típicamente
- Usuarios concurrentes: cientos o miles (la app entera)
- Prioridad: latencia baja (respuesta en milisegundos)
- Modelo: normalizado (3NF) para evitar redundancia y anomalías
- Índices: muchos y específicos para búsquedas por clave primaria
- Ejemplo: PostgreSQL sirviendo la API de tu e-commerce
### OLAP: Online Analytical Processing
OLAP es el tipo de base de datos diseñada para ANALIZAR. No le importa procesar 5.000 inserciones por segundo — le importa poder leer MILLONES de filas y hacer cálculos sobre ellas en segundos. Es como el contador que cierra el mes: no procesa ventas individuales, sino que toma TODAS las ventas del mes y calcula totales, promedios, tendencias. Necesita leer mucho, rápido, pero casi nunca escribe.
- Operaciones: SELECT masivos con agregaciones, JOINs, window functions
- Filas leídas por operación: millones a miles de millones
- Usuarios concurrentes: decenas (analistas, dashboards)
- Prioridad: throughput alto (escanear mucho dato rápido)
- Modelo: desnormalizado (estrella/snowflake) para facilitar lectura
- Almacenamiento: columnar (lee solo las columnas que necesitas)
- Ejemplo: Redshift, BigQuery, Snowflake, DuckDB para análisis
### La historia: cómo nació el Data Warehouse
En los años 80, las empresas tenían sus datos en sistemas OLTP (mainframes IBM, bases Oracle). Cuando los directivos querían informes, los programadores escribían queries pesadas contra producción… y la aplicación se ralentizaba. La solución obvia: "¿y si copiamos los datos a OTRA base de datos separada, optimizada para informes?" Esa idea tan simple es el germen del Data Warehouse.
Bill Inmon publicó en 1992 "Building the Data Warehouse" y acuñó la definición formal: un repositorio de datos integrado, orientado a temas, no volátil y variante en el tiempo. Pero fue Ralph Kimball quien en 1996 con "The Data Warehouse Toolkit" hizo el concepto accesible con el modelado dimensional: hechos, dimensiones, esquema estrella. Kimball es a los warehouses lo que Martin Fowler es a los patrones de software — el que traduce la teoría en práctica.
Consejo de senior: si alguien en una entrevista te pregunta "Inmon vs Kimball", la respuesta correcta no es elegir uno. Es entender que Inmon propone un enfoque top-down (modelo corporativo primero, data marts después) mientras Kimball propone bottom-up (construye data marts dimensionales incrementalmente). En la práctica moderna, casi todo el mundo usa Kimball o variantes. Inmon es importante históricamente pero raramente se implementa puro.
### ¿Por qué no puedo simplemente hacer una réplica de lectura?
Buena pregunta. Muchos equipos empiezan así: "ponemos una réplica de PostgreSQL para lectura y los analistas consultan ahí". Funciona… hasta que no funciona. El problema es que una réplica tiene el MISMO esquema normalizado de la app. Y un esquema normalizado es terrible para análisis.
Imagina que quieres saber "ventas por categoría y mes". En un esquema normalizado de e-commerce tendrías que hacer JOIN de orders → order_items → products → categories → timestamps. Son 5 tablas. Si encima quieres filtrar por región del cliente, añades customers → addresses → regions. 7 tablas para UNA pregunta simple. Ahora imagina al analista de negocio que no sabe SQL intentando hacer eso. Imposible.
Un Data Warehouse resuelve esto DESNORMALIZANDO los datos en un modelo dimensional donde esa misma pregunta es un SELECT con UN solo JOIN: fact_sales JOIN dim_product. Punto. El warehouse es la capa que traduce el modelo técnico de la app al modelo mental del negocio.
Y la réplica tiene dos problemas operativos más. Primero: va con retraso. Dependiendo de la carga, el desfase puede ser de segundos a minutos, así que un informe "en tiempo real" en realidad muestra datos de hace un rato — y si necesitas datos del último minuto para una decisión, la réplica no sirve. Segundo: en PostgreSQL, una réplica en caliente CANCELA las consultas largas cuando el primario le manda cambios que chocan con lo que tu consulta está leyendo. Así que tu informe de 30 segundos se muere a mitad con un "ERROR: canceling statement due to conflict with recovery".
Y además hay un mito que merece desmontarse aquí, porque aparece en muchas entrevistas: "una consulta analítica bloquea las transacciones de la app". En PostgreSQL, Oracle y MySQL/InnoDB, eso NO ocurre. Los lectores no bloquean a los escritores (MVCC). Lo que SÍ pasa es peor y más sutil: (1) tu consulta llena el buffer cache con datos históricos y expulsa las páginas que la app usa a diario — por eso la app se pone lenta incluso después de que tu informe termine; (2) el GROUP BY escribe ficheros temporales en el mismo disco; (3) mientras tu transacción sigue abierta, VACUUM no puede limpiar las filas muertas y las tablas se hinchan; y (4) tu SELECT bloquea el ALTER TABLE de la siguiente migración, y detrás de ese ALTER se encola todo lo demás. Así es como un informe pesado tira una web: no por el SELECT, por el despliegue que viene después.
Error clásico que he visto en 3 empresas diferentes: "no necesitamos warehouse, tenemos una réplica de lectura". Funciona los primeros 6 meses. Después la réplica crece, las queries analíticas compiten con los reportes automáticos, nadie entiende el esquema de la app, y acabas construyendo el warehouse que dijiste que no necesitabas… pero con 6 meses de deuda técnica encima.
### Almacenamiento por filas vs columnar
Hay una diferencia técnica fundamental entre OLTP y OLAP que explica todo: cómo almacenan los datos en disco. Una base OLTP almacena por FILAS: todos los campos de un registro están juntos. Esto es perfecto para "dame TODA la información del pedido #12345" (una fila completa). Pero terrible para "dame la suma de la columna amount de 100 millones de filas" porque tiene que leer TODAS las columnas de cada fila aunque solo necesite una.
Una base OLAP almacena por COLUMNAS: todos los valores de una misma columna están juntos en disco. Para "suma de amount", lee SOLO la columna amount — ignorando completamente product_id, customer_id, timestamp, etc. Resultado: puede ser 5x-40x más rápido para queries analíticas (medido: 8× con 5 millones de filas en DuckDB frente a PostgreSQL). Además, como los valores de una columna son del mismo tipo, se comprimen mucho mejor — pero cuánto depende de la cardinalidad: una columna de country con 50 valores únicos para 100M filas se comprime 30×, una columna de IDs únicos apenas 1.2×.
1-- En OLTP (PostgreSQL por filas): lee TODA la tabla para sumar una columna2-- Medido con 5M filas: 521 MB en disco, 215 ms3SELECT date_trunc('month', order_date) AS mes,4 SUM(amount) AS total5FROM orders6GROUP BY 1;78-- En OLAP (DuckDB columnar sobre Parquet): lee SOLO order_date y amount9-- Medido con 5M filas: 13 MB en disco, 27 ms (8x más rápido)10SELECT date_trunc('month', order_date) AS mes,11 SUM(amount) AS total12FROM fact_sales13GROUP BY 1;
La misma pregunta, 8× más rápida en un motor columnar (medido con 5M filas). No es magia — es que lee menos datos.
### El Data Warehouse en la arquitectura moderna
En 2024, un Data Warehouse no es un servidor misterioso en un sótano. Es un servicio cloud (Redshift, BigQuery, Snowflake) o un motor local (DuckDB) que recibe datos transformados de tus fuentes operacionales. Se alimenta mediante procesos ETL/ELT que extraen datos de la app, los transforman y los cargan en un modelo dimensional. Los analistas y herramientas de BI (Tableau, Metabase, Looker) consultan el warehouse directamente.
Lo que le diría a mi yo de hace 10 años: no subestimes DuckDB. Es un motor OLAP columnar que puedes instalar con pip y usar en tu portátil. Para aprender modelado dimensional, es perfecto: no necesitas un cluster de Redshift ni una cuenta de Snowflake. Todo lo que enseñamos en esta skill lo puedes practicar con DuckDB en tu máquina.
### El viaje del dato: de la app al dashboard (las capas)
Los datos no saltan directamente de la base de la app al dashboard del CEO. Pasan por CAPAS, cada una con un propósito. Piensa en ello como una fábrica: la materia prima entra por un lado, pasa por estaciones de limpieza y ensamblaje, y sale como producto terminado. En esta skill verás este patrón una y otra vez:
- 01.Raw / Staging — Los datos tal cual llegan de la fuente (la app, una API, un CSV). Sin modificar. Es tu "copia de seguridad" del dato original.
- 02.Intermediate / Transformación — Limpios, normalizados, con tipos correctos. Aquí aplicas reglas de negocio y unes fuentes diferentes.
- 03.Marts / Gold — Tablas listas para consumir. Modeladas en estrella (hechos + dimensiones). Es lo que consultan los analistas y los dashboards.
Este patrón de capas tiene muchos nombres según la empresa: Raw→Silver→Gold (Databricks), Staging→Intermediate→Marts (dbt), Bronze→Silver→Gold (Delta Lake). Los nombres cambian pero la idea es siempre la misma: separar el dato crudo del dato listo para analizar. En esta skill nos centramos en la capa final (Marts) — el modelado dimensional que hace que las queries sean rápidas y simples.
### Resumen: cuándo usar cada mundo
- Usa OLTP (PostgreSQL, MySQL) para: la base de datos de tu aplicación, transacciones en tiempo real, operaciones CRUD
- Usa OLAP (Redshift, DuckDB) para: informes históricos, dashboards, análisis de tendencias, preguntas ad-hoc del negocio
- Nunca lances queries analíticas pesadas contra producción — es la regla #1 del data engineering
- El puente entre ambos mundos es el proceso ETL/ELT que veremos en la lección 6 de esta skill
## ejercicios
Identificar OLTP vs OLAP
El CTO te presenta 6 queries y quiere saber cuáles deberían ejecutarse en la base operacional y cuáles en el warehouse. Clasifícalas añadiendo un comentario -- OLTP o -- OLAP antes de cada una.
Diagnosticar problemas de analizar en OLTP
Tu equipo de analistas lanza queries contra la base de producción y el equipo de backend se queja. Escribe una query que demuestre el problema: consulta las ventas mensuales de los últimos 2 años agrupadas por categoría de producto. Incluye un comentario explicando por qué esta query es problemática en producción.
Calcular la ventaja del almacenamiento columnar
Una tabla tiene 10 columnas y 100 millones de filas. Cada columna pesa 8 bytes por fila. Si una query solo necesita 2 columnas, calcula cuántos GB lee un motor por filas vs un motor columnar. Escríbelo como comentario SQL con los cálculos.
Diseñar una tabla analítica simple
Transforma este esquema normalizado de 3 tablas (orders, customers, products) en UNA sola tabla desnormalizada óptima para análisis. La tabla debe permitir responder "ventas por país, categoría y mes" con un simple GROUP BY sin JOINs.
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...