Saltar al contenido

lección 4

Del clic al evento: el modelo de datos de eventos y cómo se consulta con SQL

Qué es un evento, cómo se estructura una tabla de eventos crudos, y cómo preguntarle cosas con SQL. El paso de "qué compró" a "qué hizo antes de comprar".

55 min

Tienes delante una tabla de pedidos impecable: fecha, cliente, importe, productos, descuento aplicado. Con ella respondes sin despeinarte "¿qué se ha vendido esta semana?" o "¿cuánto factura cada canal?". Pero llega una pregunta distinta: "¿qué hizo el usuario ANTES de comprar? ¿Qué productos miró, cuáles añadió al carrito y luego quitó, en qué punto dudó?". Y ahí la tabla se queda muda. Solo tiene una fila por compra consumada: registra el final de la historia, no el camino que llevó hasta él. Peor aún, de los usuarios que NO compraron —que suelen ser la enorme mayoría— no hay ni rastro, porque nunca generaron un pedido que anotar. Una tabla de transacciones te dice el resultado y esconde todo lo demás. Para ver el recorrido completo necesitas un tipo de datos distinto: el modelo de eventos.

Esa necesidad — saber no solo el resultado sino cada paso que dio el usuario — es lo que hizo nacer el modelo de datos de eventos (event-based analytics). Es la razón por la que empresas como Spotify, Netflix, Airbnb o cualquier app que uses en tu móvil registran cada clic, cada scroll, cada búsqueda y cada segundo que pasas mirando una pantalla. No porque sean cotillas: porque sin esos datos, no pueden responder las preguntas que de verdad mueven el producto.

### Qué es un evento

Un evento es una acción que un usuario realiza en un producto digital, registrada con un sello de tiempo (timestamp) y un conjunto de propiedades que la describen. "María hizo clic en Añadir al carrito el producto zapatillas-running-42 el 15 de enero a las 14:32:07 desde su móvil." Eso es un evento. Cada vez que un usuario hace algo — ver una página, hacer clic en un botón, buscar un término, completar una compra — se genera una fila nueva en la tabla de eventos.

La analogía más clara es la de una cámara de seguridad en una tienda física. La caja registradora (tu tabla de pedidos) te dice quién compró y cuánto. Pero la cámara te dice todo lo demás: quién entró y se fue sin comprar, quién estuvo veinte minutos mirando la sección de ofertas, quién cogió un producto del estante y lo devolvió. El modelo de eventos es la cámara de seguridad de tu producto digital.

### Anatomía de un evento

Todo evento, sin importar la herramienta que lo capture (Mixpanel, Amplitude, Segment, un sistema propio), tiene la misma estructura básica. Son cuatro campos que nunca faltan:

  1. 01.event_name — qué pasó. El nombre de la acción: page_viewed, button_clicked, cart_added, purchase_completed. Es el verbo de la frase.
  2. 02.user_id — quién lo hizo. El identificador único del usuario. Puede ser un id interno, un email hasheado, o un identificador anónimo si aún no se ha registrado.
  3. 03.timestamp — cuándo pasó. La fecha y hora exacta, normalmente con precisión de milisegundos y en zona horaria UTC.
  4. 04.properties — el contexto. Todo lo demás que describe ese evento concreto: qué producto añadió al carrito, desde qué página vino, qué dispositivo usaba, cuánto costó. Puede ser un objeto JSON o columnas separadas.
Todo evento tiene estos cuatro campos. Las properties cambian según el tipo de evento; los otros tres son universales.

Consejo de senior: las properties son donde se juega la partida. Un evento "purchase_completed" sin la propiedad "amount" es inútil para calcular ingresos. Un evento "page_viewed" sin la propiedad "page_url" es inútil para saber qué páginas se visitan. Antes de instrumentar (es decir, de programar la captura de eventos en el producto), el analista debe definir qué propiedades necesita cada evento. Si no lo haces, te encontrarás seis meses después con millones de filas a las que les falta el dato clave.

### Taxonomía de eventos: poner orden en el caos

Una taxonomía de eventos es la lista organizada de todos los eventos que tu producto registra, con su nombre, su descripción y sus propiedades. Es el diccionario de datos del producto. Sin ella, cada equipo inventa sus propios nombres — marketing llama "sign_up" a lo que producto llama "registration_completed" y lo que ingeniería registra como "user_created" — y nadie puede cruzar datos con nadie.

Los eventos se clasifican en familias según lo que registran:

  • Eventos de navegación — el usuario ve cosas: page_viewed, screen_viewed, tab_switched. Son los más abundantes y los menos informativos por sí solos, pero imprescindibles para reconstruir el recorrido.
  • Eventos de interacción — el usuario hace cosas: button_clicked, link_clicked, form_submitted, search_performed. Indican intención.
  • Eventos de negocio — el usuario avanza en el embudo: signup_completed, cart_added, checkout_started, purchase_completed, subscription_renewed. Son los que directamente mueven métricas de negocio.
  • Eventos de sistema — los genera el producto, no el usuario: email_sent, notification_delivered, experiment_assigned. Útiles para atribución y diagnóstico.

### Convenciones de nombrado: objeto_acción

El estándar de facto en la industria es nombrar eventos con el patrón objeto_acción (o acción_objeto, según la empresa). La idea es que el nombre diga QUÉ COSA y QUÉ LE PASÓ, en ese orden. Así, cuando ordenas alfabéticamente tu lista de eventos, todos los relacionados con el carrito quedan juntos, todos los de checkout juntos, todos los de búsqueda juntos.

1-- Patron: objeto_accion (agrupa por entidad)
2cart_viewed
3cart_added
4cart_removed
5checkout_started
6checkout_completed
7search_performed
8search_result_clicked
9product_viewed
10product_shared
11
12-- Anti-patron: verbos sueltos sin estructura
13add_to_cart -- add que? a que carrito?
14clicked -- clicked donde? que boton?
15view -- view de que?

Convención objeto_acción vs. nombres sueltos sin estructura

Nombrar mal tus eventos es deuda técnica que se paga con interés compuesto. He visto empresas con tres años de datos donde el mismo evento se llama "addToCart", "add_to_cart" y "cart_add" según quién programó esa pantalla. Resultado: para calcular algo tan básico como "cuántos productos se añadieron al carrito esta semana" necesitas un WHERE event_name IN con seis variantes. Y siempre te falta una. Define la convención ANTES de instrumentar, y aplica una validación automática que rechace eventos que no la cumplan.

### Propiedades universales y propiedades específicas

Las propiedades de un evento se dividen en dos grupos. Las universales acompañan a TODOS los eventos, sin importar su tipo. Las específicas solo tienen sentido para ciertos eventos.

  • Universales (las llevan TODOS los eventos): user_id, timestamp, session_id (agrupa acciones de una misma visita), platform (ios, android, web), app_version, country.
  • Específicas de cart_added: product_id, product_name, price, quantity, category.
  • Específicas de purchase_completed: order_id, total_amount, payment_method, coupon_code, items_count.
  • Específicas de search_performed: query_text, results_count, filters_applied.
  • Específicas de page_viewed: page_url, page_title, referrer (de dónde venía el usuario).
Las universales viajan con todos los eventos. Las específicas dependen del tipo de acción.

### Modelo transaccional vs. modelo de eventos

Vamos a poner las dos formas de modelar datos una al lado de la otra, porque entender la diferencia es entender POR QUÉ existe el modelo de eventos.

El modelo transaccional es el clásico: una tabla de pedidos con una fila por transacción completada. Cada fila es un HECHO DE NEGOCIO cerrado. Compra realizada, dinero cobrado, producto enviado. Es el modelo que usaron los negocios durante décadas, y sigue siendo perfecto para responder "cuánto vendimos", "cuál es el ticket medio", "qué producto vende más". Son preguntas de resultado.

El modelo de eventos es diferente: tiene MUCHAS filas por cada usuario, una por cada acción que realizó. No solo registra el final (la compra), sino todo el camino: qué páginas visitó, qué productos miró, qué buscó, qué añadió al carrito y luego quitó. Permite responder preguntas de PROCESO: "¿qué hacen los usuarios antes de comprar?", "¿en qué punto abandonan?", "¿los que buscan compran más que los que navegan?". Son preguntas de comportamiento.

La tabla transaccional registra el resultado. La tabla de eventos registra el camino completo, incluido el de quien no llegó al final.

### Por qué las empresas digitales migraron a eventos

La respuesta corta es: porque las preguntas cambiaron. Cuando Amazon empezó a vender libros online en 1995, su tabla de pedidos le bastaba para saber qué libros vendían más. Pero en algún momento alguien preguntó: "la gente que compra este libro, ¿qué MÁS mira?" Y la tabla de pedidos no podía responder — solo tenía compras, no miradas. Así que empezaron a registrar las visitas a página de producto. Y luego las búsquedas. Y luego los clics en recomendaciones. Y sin darse cuenta, habían construido un modelo de eventos. De ahí salió "los clientes que compraron esto también compraron aquello" — que no era machine learning ni inteligencia artificial: era un GROUP BY sobre una tabla de eventos que decía qué productos miraban los mismos usuarios.

La necesidad concreta que empuja la migración es siempre la misma: quiero saber qué hace el usuario ANTES del momento que ya mido. Si mido compras, quiero saber qué hace antes de comprar. Si mido bajas (churn, es decir, cancelaciones de suscripción), quiero saber qué hizo el usuario en las semanas previas a darse de baja. Si mido activación, quiero saber por qué pantallas pasó el usuario que NO se activó. El modelo transaccional solo tiene el "después". El modelo de eventos tiene el "antes", el "durante" y el "después".

Consejo de senior: esto te lo van a preguntar en la entrevista. "¿Qué diferencia hay entre una tabla de transacciones y una tabla de eventos?" La respuesta no es técnica — es de negocio. La tabla de transacciones responde "qué pasó al final". La tabla de eventos responde "qué camino llevó ahí" y, lo que es más importante, "qué camino siguieron los que NO llegaron". Es la diferencia entre medir el éxito y entender el fracaso.

### Cómo se ve en SQL: la tabla de eventos

Vamos a ver cómo se consulta una tabla de eventos real. En la práctica, la tabla suele llamarse algo como events, raw_events, o product_events, y tiene esta estructura:

1-- Estructura tipica de una tabla de eventos
2CREATE TABLE events (
3 event_id VARCHAR PRIMARY KEY, -- identificador unico del evento
4 event_name VARCHAR NOT NULL, -- que paso: page_viewed, cart_added...
5 user_id VARCHAR NOT NULL, -- quien lo hizo
6 timestamp TIMESTAMP NOT NULL, -- cuando paso (UTC)
7 session_id VARCHAR, -- agrupa acciones de una misma visita
8 platform VARCHAR, -- ios, android, web
9 properties JSON -- contexto especifico del evento
10);

Estructura básica de una tabla de eventos en SQL

La consulta más básica sobre una tabla de eventos es filtrar por event_name. Quieres saber cuántas compras hubo esta semana? Filtras por event_name = purchase_completed. Quieres saber cuántos usuarios añadieron algo al carrito? Filtras por event_name = cart_added y cuentas usuarios únicos. Es SELECT + WHERE + GROUP BY aplicado a una tabla con millones de filas y unos pocos event_name distintos.

1-- Ejemplo: eventos de una semana para un ecommerce
2-- Contar eventos por tipo
3SELECT
4 event_name,
5 COUNT(*) AS total_eventos,
6 COUNT(DISTINCT user_id) AS usuarios_unicos
7FROM events
8WHERE timestamp >= '2024-01-15'
9 AND timestamp < '2024-01-22'
10GROUP BY event_name
11ORDER BY total_eventos DESC;

La consulta más típica: contar eventos por tipo en un periodo

### JSON o columnas: dos formas de guardar las propiedades

Hay dos escuelas para almacenar las propiedades específicas de cada evento. La primera es un campo JSON que contiene todo el contexto: {"product_id": "zap-42", "price": 89.99, "category": "running"}. La segunda es una tabla con muchas columnas, una por cada propiedad posible, donde la mayoría serán NULL para cada evento concreto.

Ambas tienen ventajas y desventajas. El JSON es flexible (no hace falta cambiar el esquema para añadir una propiedad nueva) pero más lento de consultar y más difícil de validar. Las columnas separadas son rápidas y tipadas pero rígidas (añadir una propiedad nueva requiere alterar la tabla). En la práctica, la mayoría de herramientas modernas (Mixpanel, Amplitude, Snowplow) usan JSON en la ingesta y luego lo aplanan (flatten) en columnas para el análisis. Tú, como analista, normalmente te encuentras la versión aplanada o usas funciones JSON para extraer lo que necesitas.

1-- Extraer un campo del JSON en DuckDB
2SELECT
3 user_id,
4 timestamp,
5 json_extract_string(properties, '$.product_id') AS product_id,
6 CAST(json_extract(properties, '$.price') AS DOUBLE) AS price
7FROM events
8WHERE event_name = 'cart_added'
9 AND timestamp >= '2024-01-15';

Extraer propiedades de un campo JSON con DuckDB

### El volumen: por qué importa y por qué no asusta

Una tabla de eventos es ENORME comparada con una tabla de pedidos. Un ecommerce mediano con 50.000 visitas diarias puede generar 2-5 millones de eventos al día (cada visita genera decenas de eventos: páginas vistas, clics, scrolls). En un mes son 100 millones de filas. En un año, más de mil millones. Esto asusta si vienes de tablas de pedidos con 100.000 filas al mes.

Pero no dejes que el volumen te paralice. Como analista, nunca consultas "todos los eventos de todos los tiempos". Siempre filtras por periodo (esta semana, este mes), por tipo de evento (solo cart_added), por segmento de usuario (solo usuarios de iOS), o por combinación de los tres. Y los motores analíticos modernos (DuckDB, BigQuery, Snowflake, Redshift) están diseñados exactamente para esto: escanear millones de filas filtradas por columna a velocidad absurda, porque almacenan los datos en formato columnar.

Consejo de senior: cuando te enfrentes por primera vez a una tabla de eventos, empieza siempre con la misma query de reconocimiento: SELECT event_name, COUNT(*) FROM events WHERE timestamp >= fecha_reciente GROUP BY event_name ORDER BY 2 DESC. Te dice qué tipos de eventos existen, cuáles son los más frecuentes, y te da una idea del volumen. Es el equivalente a abrir la puerta y mirar la habitación antes de entrar.

### El viaje histórico: de la hoja de pedidos al streaming de eventos

La evolución es más o menos esta. En los 90, las empresas tenían bases de datos de pedidos (Oracle, SQL Server) y sacaban informes mensuales en papel. En los 2000, las webs empezaron a registrar "visitas" con herramientas como Google Analytics — pero eran contadores agregados, no eventos individuales. En los 2010, empresas como Mixpanel (2009) y Amplitude (2012) democratizaron el event tracking: cualquier empresa podía registrar eventos individuales sin construir la infraestructura desde cero. Y desde 2015 aproximadamente, Segment (ahora de Twilio) estandarizó el concepto de "tracking plan": un contrato entre producto, ingeniería y datos que define exactamente qué eventos se capturan y con qué propiedades.

El resultado hoy es que cualquier producto digital serio tiene una tabla de eventos como fuente de verdad de comportamiento. El analista no la construye (eso es trabajo de ingeniería), pero la consulta todos los días. Y una gran parte de tu trabajo será exactamente eso: hacer las preguntas correctas a una tabla de eventos con SQL.

Cada década añadió una capa de detalle. Hoy el estándar es registrar cada acción individual.

### Resumen: qué has aprendido

  • Un evento es una acción de un usuario, con un nombre, un timestamp y propiedades que la describen.
  • La tabla de eventos registra TODO el comportamiento, no solo las transacciones completadas. Eso permite responder "qué hicieron los que NO compraron".
  • Una taxonomía de eventos organizada (convención objeto_acción) evita el caos cuando el producto crece.
  • Las propiedades se dividen en universales (user_id, timestamp, session_id, platform) y específicas de cada tipo de evento.
  • El modelo de eventos no sustituye al modelo transaccional: lo complementa. Las preguntas de resultado se responden con pedidos; las de comportamiento, con eventos.
  • Consultar una tabla de eventos es SQL básico: filtrar por event_name, agrupar por usuario o por periodo, y extraer propiedades del JSON cuando hace falta.

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...