Cómo crear una Dimension Degenerate (Degenerate Dimension) en Modelado de Datos (Kimball)
Este tutorial muestra cómo crear una Dimension Degenerate (degenerada) siguiendo los principios Kimball: cuándo y por qué mantener atributos de transacción directamente en la fact table en lugar de crear una dimensión separada. Aprender a modelar degenerate dimensions ayuda a simplificar consultas y a reducir joins innecesarios en escenarios de facturas, pedidos o transacciones únicas.
Requisitos previos
- Conocimientos básicos de SQL (SELECT, JOIN, INSERT).
- Comprensión del concepto de star schema y de fact/dimension.
- Una base de datos de prueba (por ejemplo SQL Server, PostgreSQL o MySQL).
Paso 1: Identificar cuándo usar una Degenerate Dimension
Una Degenerate Dimension es un atributo ligado a la transacción que no necesita identidad ni atributos adicionales que justifiquen una dimensión separada. Ejemplos típicos: número de factura, código de transacción, referencia externa. Úsela cuando el atributo es único por fila de fact y no va a ser compartido entre fact tables.
Paso 2: Verificar requisitos de consulta y granularidad
Antes de decidir mantener el campo en la fact table, confirme que los informes no necesitan atributos adicionales, historial o conformidad que exigirían una dimensión. Piense en el rendimiento: si muchos informes solo filtran por ese campo, una Degenerate Dimension (en la fact) reduce joins.
Paso 3: Definir la estructura de la fact table con la Degenerate Dimension
Creé la fact table incluyendo la clave de la fact (surrogate key o natural), medidas y el campo degenerado como columna no referenciada a una dimensión. Asegure el tipo de datos adecuado y la indexación cuando sea necesario para filtros frecuentes.
-- Exemplo em SQL (SQL Server sintaxe genérica) CREATE TABLE FactSales (
SaleID BIGINT PRIMARY KEY, -- surrogate key da fact
InvoiceNumber VARCHAR(50) NOT NULL, -- Degenerate Dimension
CustomerKey INT NOT NULL, -- FK para Dimension Customer
ProductKey INT NOT NULL, -- FK para Dimension Product
SaleDateKey INT NOT NULL, -- FK para Dimension Date
Quantity INT,
Amount DECIMAL(18,2)
);
-- Índice para procurar por InvoiceNumber rapidamente
CREATE INDEX IX_FactSales_InvoiceNumber ON FactSales(InvoiceNumber);
Paso 4: Carga ETL/ELT: poblar la Degenerate Dimension
En el proceso ETL/ELT, solo mapee el valor del campo de transacción directamente a la columna de la fact. No intente crear una surrogate key separada. Trate duplicados y normalización únicamente si es necesario para garantizar integridad (p. ej.: limpieza de espacios, formato consistente).
-- Exemplo simples de INSERT durante ETL INSERT INTO FactSales (SaleID, InvoiceNumber, CustomerKey, ProductKey, SaleDateKey, Quantity, Amount)
SELECT
s.SourceSaleID, -- pode ser surrogate gerado
TRIM(s.InvoiceNo),
d.CustomerKey,
p.ProductKey,
dd.DateKey,
s.Quantity,
s.TotalAmount
FROM StagingSales s
JOIN DimCustomer d ON s.CustomerID = d.CustomerID
JOIN DimProduct p ON s.ProductCode = p.ProductCode
JOIN DimDate dd ON CAST(s.SaleDate AS DATE) = dd.FullDate
WHERE s.IsActive = 1;
Paso 5: Tratar errores comunes
Errores comunes: 1) Tratar InvoiceNumber como dimensión y luego descubrir que es única por fila — crea redundancia. 2) No indexar InvoiceNumber cuando se usa en filtros — consultas lentas. 3) Asumir inmutabilidad cuando los números pueden cambiar (p. ej.: corrección de factura) — definir política: actualizar la fact o crear evento de corrección.
Verificar el resultado
Confirme que la Degenerate Dimension funciona ejecutando consultas reales: filtrado por InvoiceNumber, agregaciones por Customer y verificación de los planes de ejecución. Pruebas a realizar:
- SELECT por InvoiceNumber — debe devolver la fila correcta y ser rápido.
- Recuentos de invoices distintos — comparar con la fuente.
- Informes que agregan por Customer/Date — garantizar que no hay exceso de joins.
-- Exemplos de verificação
-- 1) Procurar fatura específica
SELECT * FROM FactSales WHERE InvoiceNumber = 'INV-2026-0001';
-- 2) Contar invoices distintos por día
SELECT SaleDateKey, COUNT(DISTINCT InvoiceNumber) AS NumInvoices
FROM FactSales
GROUP BY SaleDateKey;
Conclusión
Mantener una Degenerate Dimension en la fact table simplifica el modelo cuando el atributo es único por transacción y no tiene atributos propios. Próximos pasos: evaluar indexación, políticas de actualización e impacto en informes. Consejo: documente siempre por qué un campo es degenerado — esto ahorrará tiempo al equipo cuando estén optimizando consultas.