SQL Academy · Lección

Tablas de hechos y dimensiones

Los componentes básicos de un almacén de datos.

Lección 2 de 413 pasos

Tablas de hechos y dimensiones es una lección gratuita de SQL Academy en CoddyKit. Esta es la lección 2 de 4. Puedes leer la lección completa abajo gratuitamente — luego la practicas en el navegador con un editor de código integrado y un tutor de IA 24/7. Forma parte de la ruta de aprendizaje de SQL Academy, y tu progreso se sincroniza en la web y la app de CoddyKit. El curso de SQL Academy incluye 4 lecciones en total.

¿Qué es un almacén de datos?

Un almacén de datos es un repositorio central diseñado para informes y consultas analíticas. A diferencia de una base de datos transaccional, optimizada para escrituras rápidas, un almacén está ajustado para realizar lecturas rápidas en grandes volúmenes de datos históricos.

La forma más habitual de organizar un almacén es mediante un esquema de estrella, que divide los datos en dos tipos de tablas: tablas de hechos y tablas de dimensiones.

Definición de las tablas de hechos

Una tabla de hechos almacena eventos cuantificables y medibles: aquello que desea analizar. Cada fila representa una ocurrencia de un evento empresarial, como una venta, una visita a una página web o un ticket de soporte.

Las tablas de hechos suelen ser anchas (muchas filas) y estrechas (pocas columnas), y la mayoría de sus columnas son claves foráneas que apuntan a tablas de dimensiones o medidas numéricas como quantity o revenue.

CREATE TABLE fact_sales (
  sale_id      SERIAL PRIMARY KEY,
  date_key     INT NOT NULL,
  product_key  INT NOT NULL,
  customer_key INT NOT NULL,
  store_key    INT NOT NULL,
  quantity     INT NOT NULL,
  unit_price   NUMERIC(10, 2) NOT NULL,
  total_amount NUMERIC(12, 2) NOT NULL
);

Definición de las tablas de dimensiones

Una tabla de dimensiones almacena atributos descriptivos que proporcionan contexto a cada hecho. Algunos ejemplos son una dimensión de producto (nombre, categoría, marca) o una dimensión de fecha (día, mes, trimestre, año).

Las tablas de dimensiones suelen ser pequeñas (menos filas), pero anchas (muchas columnas descriptivas). Se unen a la tabla de hechos mediante claves enteras sustitutas.

CREATE TABLE dim_product (
  product_key  SERIAL PRIMARY KEY,
  product_name VARCHAR(200) NOT NULL,
  category     VARCHAR(100),
  brand        VARCHAR(100),
  unit_cost    NUMERIC(10, 2)
);

CREATE TABLE dim_customer (
  customer_key SERIAL PRIMARY KEY,
  full_name    VARCHAR(200) NOT NULL,
  email        VARCHAR(200),
  country      VARCHAR(100),
  segment      VARCHAR(50)
);

La dimensión de fecha

La dimensión de fecha es la dimensión más habitual en cualquier almacén. En lugar de almacenar un TIMESTAMP sin procesar en la tabla de hechos, se almacena una clave entera que hace referencia a una tabla de calendario creada previamente.

Esto permite que las consultas filtren o agrupen por trimestre fiscal, día de la semana, indicadores de festivos y otros atributos del calendario sin realizar operaciones aritméticas con fechas durante la consulta.

CREATE TABLE dim_date (
  date_key       INT PRIMARY KEY,  -- e.g. 20240315
  full_date      DATE NOT NULL,
  day_of_week    VARCHAR(10),
  day_of_month   INT,
  month_num      INT,
  month_name     VARCHAR(20),
  quarter        INT,
  year           INT,
  is_holiday     BOOLEAN DEFAULT FALSE,
  fiscal_quarter INT
);

-- Sample row
INSERT INTO dim_date VALUES
  (20240315, '2024-03-15', 'Friday', 15, 3, 'March', 1, 2024, FALSE, 2);

El patrón de esquema de estrella

Cuando dibuja un diagrama con una tabla de hechos en el centro y tablas de dimensiones que se extienden hacia afuera, parece una estrella, de ahí el nombre de esquema de estrella.

Las claves foráneas de la tabla de hechos apuntan a las claves primarias de cada dimensión. Normalmente, las consultas unen la tabla de hechos a una o más dimensiones para añadir contexto descriptivo a los valores numéricos sin procesar.

-- Join fact to two dimensions to enrich a sales report
SELECT
  dp.product_name,
  dp.category,
  SUM(fs.quantity)     AS total_units_sold,
  SUM(fs.total_amount) AS total_revenue
FROM fact_sales fs
JOIN dim_product  dp ON dp.product_key  = fs.product_key
JOIN dim_date     dd ON dd.date_key     = fs.date_key
WHERE dd.year = 2024
GROUP BY dp.product_name, dp.category
ORDER BY total_revenue DESC;

Claves sustitutas frente a claves naturales

Las tablas de dimensiones utilizan claves sustitutas: enteros sintéticos generados por la base de datos, independientes de cualquier significado empresarial. Las claves naturales (como el SKU de un producto o el correo electrónico de un cliente) pueden cambiar con el tiempo, pero las claves sustitutas nunca cambian.

El uso de claves sustitutas aísla la tabla de hechos de los cambios en los sistemas de origen y hace que las uniones sean más rápidas, ya que comparar enteros es más barato que comparar cadenas.

-- Surrogate key approach: integer join is fast
SELECT fs.sale_id, dc.full_name, fs.total_amount
FROM fact_sales fs
JOIN dim_customer dc ON dc.customer_key = fs.customer_key
WHERE dc.country = 'Germany'
LIMIT 10;

-- Natural key approach (avoid in warehouses): slower string join
-- JOIN dim_customer dc ON dc.email = fs.customer_email

Granularidad: el nivel de detalle de una tabla de hechos

La granularidad de una tabla de hechos describe exactamente qué representa una fila. Antes de crear un almacén, debe declarar la granularidad; por ejemplo, una fila por cada línea de producto individual de un pedido de venta.

Una granularidad bien definida evita las agregaciones ambiguas. Si distintas filas representan eventos diferentes, los resultados de SUM y COUNT carecerán de sentido.

-- Grain: one row per product per order line
-- Each row = one line item sold in one transaction
SELECT
  sale_id,
  date_key,
  product_key,
  quantity,
  unit_price,
  total_amount
FROM fact_sales
WHERE date_key = 20240315
ORDER BY sale_id;

Medidas aditivas, semiaditivas y no aditivas

Los hechos se clasifican en tres tipos según cómo se pueden agregar:

  • Aditivos: se pueden sumar en todas las dimensiones (p. ej., revenue, quantity).
  • Semiaditivos: se pueden sumar en algunas dimensiones, pero no en todas (p. ej., el balance de una cuenta se puede sumar entre clientes, pero no a lo largo del tiempo).
  • No aditivos: no se pueden sumar de forma significativa (p. ej., unit_price, ratio). Use AVG u otras agregaciones.
SELECT
  dd.month_name,
  SUM(fs.total_amount)         AS total_revenue,   -- additive
  AVG(fs.unit_price)           AS avg_unit_price,   -- non-additive: use AVG
  SUM(fs.quantity)             AS total_units       -- additive
FROM fact_sales fs
JOIN dim_date dd ON dd.date_key = fs.date_key
WHERE dd.year = 2024
GROUP BY dd.month_name, dd.month_num
ORDER BY dd.month_num;

Dimensiones que cambian lentamente (SCD de tipo 1 y 2)

Los atributos de las dimensiones cambian con el tiempo: un cliente cambia de país o un producto cambia de categoría. Las dimensiones que cambian lentamente (SCD) gestionan estos cambios:

  • Tipo 1: sobrescriba el valor anterior. Es sencillo, pero se pierde el historial.
  • Tipo 2: añada una nueva fila con una nueva clave sustituta y fechas de vigencia. Conserva todo el historial para que los hechos históricos sigan apuntando a la versión correcta de la dimensión.
-- SCD Type 2: add a new version of the row
ALTER TABLE dim_customer ADD COLUMN valid_from DATE;
ALTER TABLE dim_customer ADD COLUMN valid_to   DATE;
ALTER TABLE dim_customer ADD COLUMN is_current BOOLEAN DEFAULT TRUE;

-- Expire the old row
UPDATE dim_customer
SET is_current = FALSE,
    valid_to   = CURRENT_DATE - INTERVAL '1 day'
WHERE email = 'anna@example.com' AND is_current = TRUE;

-- Insert the updated version
INSERT INTO dim_customer (full_name, email, country, segment, valid_from, valid_to, is_current)
VALUES ('Anna Muller', 'anna@example.com', 'Austria', 'Premium', CURRENT_DATE, '9999-12-31', TRUE);

Dimensiones degeneradas

A veces, un atributo de dimensión no necesita su propia tabla. Una dimensión degenerada es una clave de dimensión que reside directamente en la tabla de hechos sin una tabla de dimensiones correspondiente.

Algunos ejemplos clásicos son los números de pedido, los números de factura o los identificadores de tickets. Proporcionan contexto para profundizar en los datos, pero no tienen otras columnas descriptivas que merezca la pena almacenar en una tabla independiente.

-- order_number is a degenerate dimension:
-- it lives in the fact table, no dim_order table needed
CREATE TABLE fact_order_lines (
  line_id      SERIAL PRIMARY KEY,
  order_number VARCHAR(20) NOT NULL,  -- degenerate dimension
  date_key     INT NOT NULL,
  product_key  INT NOT NULL,
  customer_key INT NOT NULL,
  quantity     INT NOT NULL,
  line_total   NUMERIC(12, 2) NOT NULL
);

SELECT order_number, SUM(line_total) AS order_total
FROM fact_order_lines
GROUP BY order_number
ORDER BY order_total DESC
LIMIT 5;

Consultar el esquema de estrella completo

En conjunto, una consulta típica de un almacén une la tabla de hechos a varias dimensiones, aplica filtros a los atributos de las dimensiones y agrega medidas de la tabla de hechos.

El optimizador puede gestionar estas uniones entre varias tablas de forma eficiente porque las claves foráneas de la tabla de hechos están indexadas y las tablas de dimensiones son relativamente pequeñas.

SELECT
  dd.year,
  dd.quarter,
  dp.category,
  dc.country,
  SUM(fs.quantity)     AS units_sold,
  SUM(fs.total_amount) AS revenue
FROM fact_sales fs
JOIN dim_date     dd ON dd.date_key     = fs.date_key
JOIN dim_product  dp ON dp.product_key  = fs.product_key
JOIN dim_customer dc ON dc.customer_key = fs.customer_key
WHERE dd.year IN (2023, 2024)
  AND dp.category = 'Electronics'
GROUP BY dd.year, dd.quarter, dp.category, dc.country
ORDER BY dd.year, dd.quarter, revenue DESC;

Comprobación rápida: hechos frente a dimensiones

Compruebe su comprensión de las diferencias entre las tablas de hechos y las tablas de dimensiones en un esquema de estrella.

Resumen de la lección

En esta lección ha aprendido los componentes básicos de un esquema de estrella de un almacén de datos:

  • Las tablas de hechos contienen eventos medibles (ventas, clics y transacciones), con medidas numéricas y claves foráneas.
  • Las tablas de dimensiones proporcionan contexto descriptivo (quién, qué, dónde y cuándo) mediante claves sustitutas.
  • La granularidad define exactamente qué representa cada fila de hechos; declárela antes de construir el almacén.
  • Las medidas son aditivas, semiaditivas o no aditivas, lo que determina cómo se agregan.
  • Las SCD de tipo 2 conservan los valores históricos de las dimensiones al añadir nuevas filas con fechas de vigencia.
  • Las dimensiones degeneradas residen en la tabla de hechos cuando no tienen atributos adicionales que describir.

Comprender las tablas de hechos y de dimensiones es la base para crear almacenes rápidos, escalables y potentes para el análisis.

Gratis para empezar

Aprende SQL con un tutor de IA — gratis

Escribe y ejecuta código real en tu navegador, obtén ayuda instantánea de un tutor de IA disponible 24/7 y continúa donde lo dejaste en la web o en la aplicación.

Cursos
46
Lecciones
183

Preguntas frecuentes

¿La lección «Tablas de hechos y dimensiones» es gratis?

Sí — el texto completo de «Tablas de hechos y dimensiones» es gratis para leer aquí en la web. Para practicarla de forma interactiva (editor de código integrado y tutor de IA 24/7) y desbloquear el resto del curso de SQL Academy, actualiza a CoddyKit PRO. El curso de SQL Academy incluye 4 lecciones en total.

¿Qué aprenderé en «Tablas de hechos y dimensiones»?

Los componentes básicos de un almacén de datos. Practicas SQL Academy con código real que ejecutas directamente en el navegador, y un tutor de IA 24/7 responde tus preguntas mientras trabajas en la lección.

¿Necesito experiencia previa para empezar SQL Academy?

No se requiere experiencia previa. SQL Academy en CoddyKit está estructurado para principiantes hasta estudiantes avanzados, así que puedes empezar aquí o desde el inicio y avanzar a tu ritmo. Esta es la lección 2 de 4.

¿Cuánto tiempo toma la lección «Tablas de hechos y dimensiones»?

La mayoría de las lecciones de CoddyKit toman alrededor de 5–10 minutos. Cada una es compacta e interactiva, así que avanzas constantemente y retomas exactamente por donde dejaste en la web y la app.

¿Puedo escribir y ejecutar código en esta lección de SQL Academy?

Sí. Cada lección de SQL Academy incluye un editor de código integrado, así que escribes y ejecutas código real directamente en tu navegador y obtienes retroalimentación instantánea de IA — sin configuración local necesaria.

Todas las lecciones de este curso

  1. OLTP frente a OLAP
  2. Tablas de hechos y dimensiones
  3. Esquemas de estrella y copo de nieve
  4. Escritura de consultas analíticas
← Volver a SQL Academy