Esquemas de estrella y copo de nieve
Modele los datos para realizar análisis rápidos.
Esquemas de estrella y copo de nieve es una lección gratuita de SQL Academy en CoddyKit. Esta es la lección 3 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 esquema de almacén de datos?
En una base de datos transaccional (OLTP), se normalizan los datos para evitar la redundancia. En un almacén de datos, a menudo se desnormalizan de forma intencionada, intercambiando almacenamiento por velocidad de consulta. Dos patrones clásicos para organizar las tablas de un almacén son el esquema de estrella y el esquema de copo de nieve.
Ambos giran en torno a una tabla de hechos central rodeada de tablas de dimensiones. La diferencia está en hasta qué punto se normalizan esas dimensiones.
Tablas de hechos y tablas de dimensiones
Una tabla de hechos almacena eventos medibles: ventas, clics y envíos. Es ancha (muchas filas) y contiene medidas numéricas, además de claves foráneas que apuntan a las dimensiones.
Una tabla de dimensiones describe el contexto de cada evento: quién, qué, cuándo y dónde. Las dimensiones son más estrechas (menos filas), pero contienen más columnas descriptivas.
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,
revenue NUMERIC(12, 2) NOT NULL
);
CREATE TABLE dim_product (
product_key SERIAL PRIMARY KEY,
product_name VARCHAR(200),
category VARCHAR(100),
brand VARCHAR(100),
unit_price NUMERIC(10, 2)
);El esquema de estrella
En un esquema de estrella, cada tabla de dimensiones se conecta directamente con la tabla de hechos. Si dibuja las relaciones sobre el papel, parece una estrella: la tabla de hechos es el centro y las dimensiones son las puntas.
Las tablas de dimensiones están completamente desnormalizadas: todos los atributos descriptivos residen en una sola tabla, aunque algunos se repitan en varias filas.
-- Star schema: all product info in one flat dimension table
CREATE TABLE dim_product (
product_key SERIAL PRIMARY KEY,
product_name VARCHAR(200),
category_name VARCHAR(100), -- denormalized
subcategory VARCHAR(100), -- denormalized
brand_name VARCHAR(100), -- denormalized
brand_country VARCHAR(100), -- denormalized
unit_price NUMERIC(10, 2)
);
CREATE TABLE dim_date (
date_key INT PRIMARY KEY, -- e.g. 20240315
full_date DATE,
year INT,
quarter INT,
month INT,
month_name VARCHAR(20),
week INT,
day_of_week VARCHAR(10)
);Consulta del esquema de estrella
Las tablas de dimensiones planas hacen que las consultas sean sencillas. Se une la tabla de hechos a una o más dimensiones y se agregan los datos. No hay uniones secundarias mediante cadenas de tablas normalizadas.
Por eso los esquemas de estrella ofrecen consultas analíticas rápidas: el grafo de uniones es poco profundo.
SELECT
d.year,
d.quarter,
p.category_name,
SUM(f.revenue) AS total_revenue,
SUM(f.quantity) AS units_sold
FROM fact_sales f
JOIN dim_date d ON d.date_key = f.date_key
JOIN dim_product p ON p.product_key = f.product_key
WHERE d.year = 2024
GROUP BY d.year, d.quarter, p.category_name
ORDER BY d.quarter, total_revenue DESC;El esquema de copo de nieve
Un esquema de copo de nieve normaliza aún más las tablas de dimensiones al dividirlas en subdimensiones. Por ejemplo, en lugar de almacenar category_name y brand_name dentro de dim_product, se crean tablas independientes dim_category y dim_brand.
El diagrama resultante parece un copo de nieve: ramas de tablas relacionadas.
-- Snowflake schema: product dimension is normalized
CREATE TABLE dim_brand (
brand_key SERIAL PRIMARY KEY,
brand_name VARCHAR(100),
brand_country VARCHAR(100)
);
CREATE TABLE dim_category (
category_key SERIAL PRIMARY KEY,
category_name VARCHAR(100),
subcategory VARCHAR(100)
);
CREATE TABLE dim_product (
product_key SERIAL PRIMARY KEY,
product_name VARCHAR(200),
category_key INT REFERENCES dim_category(category_key),
brand_key INT REFERENCES dim_brand(brand_key),
unit_price NUMERIC(10, 2)
);Consulta de un esquema de copo de nieve
Consultar un esquema de copo de nieve requiere más operaciones JOIN para volver a ensamblar los datos de dimensiones que se dividieron entre varias tablas. El optimizador de consultas debe recorrer los niveles adicionales, lo que puede añadir latencia en comparación con un esquema de estrella.
Sin embargo, las dimensiones normalizadas son más pequeñas y coherentes: actualizar el nombre de una marca en una fila de dim_brand lo aplica automáticamente en todas partes.
SELECT
d.year,
c.category_name,
b.brand_name,
SUM(f.revenue) AS total_revenue
FROM fact_sales f
JOIN dim_date d ON d.date_key = f.date_key
JOIN dim_product p ON p.product_key = f.product_key
JOIN dim_category c ON c.category_key = p.category_key
JOIN dim_brand b ON b.brand_key = p.brand_key
WHERE d.year = 2024
GROUP BY d.year, c.category_name, b.brand_name
ORDER BY total_revenue DESC;Claves subrogadas frente a claves naturales
Las tablas de dimensiones suelen utilizar una clave subrogada —un entero generado por el almacén de datos (por ejemplo, SERIAL)— en lugar de una clave natural del sistema de origen.
Las claves subrogadas permanecen estables incluso cuando cambia el origen, ocupan poco espacio en tablas de hechos grandes y permiten trabajar con dimensiones de variación lenta, en las que es necesario conservar el historial.
-- Surrogate key (product_key) vs natural key (sku)
INSERT INTO dim_product (product_name, category_key, brand_key, unit_price)
VALUES ('Wireless Headphones', 3, 7, 89.99);
-- product_key is assigned by SERIAL -- the natural key (SKU) lives elsewhere
-- Natural key would be:
-- INSERT INTO dim_product (sku, product_name, ...)
-- VALUES ('WH-1000XM5', 'Wireless Headphones', ...);
-- Risky: SKU can be reused or reassigned by the source systemLa dimensión de fechas
La dimensión de fechas es especial: casi siempre está presente y normalmente se pre наuebla con fechas de muchos años. Almacenar atributos derivados (año, trimestre, nombre del mes, período fiscal e indicador de festivo) en la tabla de dimensiones evita tener que volver a calcularlos durante la consulta.
-- Populate dim_date for one year using generate_series
INSERT INTO dim_date (date_key, full_date, year, quarter, month, month_name, week, day_of_week)
SELECT
TO_CHAR(d, 'YYYYMMDD')::INT AS date_key,
d AS full_date,
EXTRACT(YEAR FROM d)::INT AS year,
EXTRACT(QUARTER FROM d)::INT AS quarter,
EXTRACT(MONTH FROM d)::INT AS month,
TO_CHAR(d, 'Month') AS month_name,
EXTRACT(WEEK FROM d)::INT AS week,
TO_CHAR(d, 'Day') AS day_of_week
FROM generate_series('2024-01-01'::DATE, '2024-12-31'::DATE, '1 day') AS d;Dimensiones de variación lenta (SCD Type 2)
¿Qué ocurre cuando un cliente cambia de ciudad o un producto cambia de categoría? Es necesario conservar el historial. SCD Type 2 inserta una nueva fila de dimensión por cada cambio y cierra la anterior con una fecha de finalización. La fila de la tabla de hechos sigue apuntando a la clave de dimensión antigua, lo que preserva la exactitud histórica.
-- SCD Type 2 customer dimension
CREATE TABLE dim_customer (
customer_key SERIAL PRIMARY KEY,
customer_id INT NOT NULL,
customer_name VARCHAR(200),
city VARCHAR(100),
country VARCHAR(100),
valid_from DATE NOT NULL,
valid_to DATE,
is_current BOOLEAN DEFAULT TRUE
);
-- When a customer moves, close old row and insert new one:
UPDATE dim_customer
SET valid_to = CURRENT_DATE - 1, is_current = FALSE
WHERE customer_id = 42 AND is_current = TRUE;
INSERT INTO dim_customer (customer_id, customer_name, city, country, valid_from, is_current)
VALUES (42, 'Alice Muller', 'Berlin', 'Germany', CURRENT_DATE, TRUE);Estrella frente a copo de nieve: ventajas y desventajas
Ningún esquema es universalmente mejor que otro. Elija según sus prioridades:
- Estrella: menos operaciones JOIN, consultas más rápidas, ETL más sencillo y mayor coste de almacenamiento. Es la mejor opción para herramientas de análisis con muchas lecturas (Tableau, Power BI).
- Copo de nieve: dimensiones normalizadas, menos redundancia y actualizaciones de dimensiones más sencillas, pero más operaciones JOIN. Es preferible cuando las dimensiones son grandes o se comparten entre varias tablas de hechos.
-- Checking how much storage the denormalized category column costs
-- in a large dim_product (star schema) vs a separate dim_category (snowflake)
SELECT
COUNT(*) AS total_products,
COUNT(DISTINCT category_name) AS unique_categories,
pg_size_pretty(
SUM(pg_column_size(category_name))
) AS category_storage
FROM dim_product;Esquema de galaxia (constelación de hechos)
Cuando un almacén de datos tiene varias tablas de hechos que comparten tablas de dimensiones, el resultado se denomina esquema de galaxia (o constelación de hechos). Por ejemplo, un almacén de datos minorista podría tener tablas de hechos independientes para ventas y devoluciones, ambas con referencias a dim_product y dim_date.
Las dimensiones compartidas garantizan filtros coherentes y facilitan las comparaciones entre hechos.
CREATE TABLE fact_returns (
return_id SERIAL PRIMARY KEY,
date_key INT NOT NULL REFERENCES dim_date(date_key),
product_key INT NOT NULL REFERENCES dim_product(product_key),
customer_key INT NOT NULL,
quantity INT NOT NULL,
refund_amount NUMERIC(12, 2) NOT NULL
);
-- Cross-fact query: net revenue = sales - refunds
SELECT
d.year,
d.month,
SUM(s.revenue) AS gross_revenue,
SUM(r.refund_amount) AS total_refunds,
SUM(s.revenue) - COALESCE(SUM(r.refund_amount), 0) AS net_revenue
FROM dim_date d
LEFT JOIN fact_sales s ON s.date_key = d.date_key
LEFT JOIN fact_returns r ON r.date_key = d.date_key
WHERE d.year = 2024
GROUP BY d.year, d.month
ORDER BY d.month;Esquemas de estrella y de copo de nieve
Compruebe cuánto entiende los esquemas de estrella y de copo de nieve.
Resumen de la lección
En esta lección exploró dos patrones fundamentales de diseño de almacenes de datos:
- Esquema de estrella: una tabla de hechos central rodeada de tablas de dimensiones planas y desnormalizadas. Menos operaciones JOIN, consultas más rápidas y un poco más de almacenamiento.
- Esquema de copo de nieve: las tablas de dimensiones se normalizan aún más en subdimensiones. Menos redundancia y actualizaciones más sencillas, pero se requieren más operaciones JOIN.
- Las tablas de hechos contienen eventos medibles; las tablas de dimensiones proporcionan contexto (quién, qué, cuándo y dónde).
- Las claves subrogadas protegen la exactitud histórica y desacoplan el almacén de datos de los cambios del sistema de origen.
- SCD Type 2 conserva el historial de las dimensiones mediante nuevas filas con fechas de validez, en lugar de sobrescribir las antiguas.
- Cuando varias tablas de hechos comparten dimensiones, el diseño se convierte en un esquema de galaxia (constelación de hechos).
Elija el esquema de estrella por su sencillez y velocidad; elija el de copo de nieve cuando las dimensiones sean grandes, se actualicen con frecuencia o se compartan entre muchas tablas de hechos.
Preguntas frecuentes
¿La lección «Esquemas de estrella y copo de nieve» es gratis?
Sí — el texto completo de «Esquemas de estrella y copo de nieve» 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 «Esquemas de estrella y copo de nieve»?
Modele los datos para realizar análisis rápidos. 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 3 de 4.
¿Cuánto tiempo toma la lección «Esquemas de estrella y copo de nieve»?
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
- OLTP frente a OLAP
- Tablas de hechos y dimensiones
- Esquemas de estrella y copo de nieve
- Escritura de consultas analíticas