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
Imagina esto: trabajas con datos en 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
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...