(+351) 21 24 10006  ·  info@bconcepts.pt
Carnaxide, Lisboa

Cómo crear una tabla de hechos en un Data Warehouse

João Barros 04 de July de 2026 4 min de lectura

La tabla de hechos es el corazón de cualquier Data Warehouse: guarda los números que el negocio quiere medir, como ventas, cantidades o costes. Una tabla de hechos bien diseñada es lo que convierte datos dispersos en un modelo listo para informes rápidos y fiables, y el secreto está en acertar con el grano y las claves.

Requisitos previos

  • Un servidor de base de datos (usamos SQL Server, pero la idea se aplica a cualquier motor).
  • Al menos dos dimensiones ya creadas (por ejemplo, DimData y DimProduto).
  • Nociones básicas de SQL (CREATE TABLE e INSERT).
  • Una herramienta para ejecutar consultas, como SQL Server Management Studio o Azure Data Studio.

Paso 1: Definir el grano de la tabla de hechos

El grano es la pregunta más importante: "¿qué representa una fila de esta tabla?". Antes de escribir cualquier SQL, decide el nivel de detalle. En este ejemplo, el grano es "una fila por producto vendido en cada transacción". Un grano claro evita errores de conteo y duplicación más adelante.

Paso 2: Identificar las dimensiones y las medidas

Con el grano definido, separa las columnas en dos grupos. Las claves foráneas conectan la tabla de hechos con las dimensiones (quién, qué, cuándo). Las medidas son los valores numéricos que vas a sumar o calcular. La mayoría de las medidas son aditivas, es decir, se pueden sumar con seguridad a través de todas las dimensiones. En nuestro caso de ventas:

  • Claves: DataKey, ProdutoKey, ClienteKey.
  • Medidas: Quantidade, ValorVenda, Desconto.

Paso 3: Crear la tabla de hechos en SQL

Ahora traducimos el diseño a una instrucción CREATE TABLE. Cada clave foránea apunta a la surrogate key de la dimensión correspondiente, y las medidas usan tipos numéricos con decimales para los valores monetarios.

CREATE TABLE FactVendas (
    VendaID      BIGINT IDENTITY(1,1) PRIMARY KEY,
    DataKey      INT NOT NULL,
    ProdutoKey   INT NOT NULL,
    ClienteKey   INT NOT NULL,
    Quantidade   INT NOT NULL,
    ValorVenda   DECIMAL(12,2) NOT NULL,
    Desconto     DECIMAL(12,2) NOT NULL DEFAULT 0,
    CONSTRAINT FK_Vendas_Data
        FOREIGN KEY (DataKey) REFERENCES DimData(DataKey),
    CONSTRAINT FK_Vendas_Produto
        FOREIGN KEY (ProdutoKey) REFERENCES DimProduto(ProdutoKey),
    CONSTRAINT FK_Vendas_Cliente
        FOREIGN KEY (ClienteKey) REFERENCES DimCliente(ClienteKey)
);

Paso 4: Cargar datos con las claves de las dimensiones

La tabla de hechos nunca guarda texto como "Lisboa" o "Teclado"; guarda la clave numérica que vino de la dimensión. Por eso, al cargar, haces un JOIN entre los datos de origen y cada dimensión para obtener la clave correcta. El siguiente ejemplo inserta una venta con las claves ya resueltas:

INSERT INTO FactVendas (DataKey, ProdutoKey, ClienteKey, Quantidade, ValorVenda, Desconto)
SELECT d.DataKey, p.ProdutoKey, c.ClienteKey, 3, 149.70, 0
FROM   DimData    d
JOIN   DimProduto p ON p.CodigoProduto = 'TEC-001'
JOIN   DimCliente c ON c.Email = 'ana@exemplo.pt'
WHERE  d.DataCompleta = '2026-07-04';

Fíjate en que no hay columnas descriptivas en la tabla de hechos: todo lo relativo a "quién" y "qué" vive en las dimensiones.

Paso 5: Mejorar el rendimiento con un índice

Las consultas de BI casi siempre filtran y agrupan por las claves de las dimensiones. Crear un índice en esas columnas ayuda al motor a encontrar las filas correctas sin leer toda la tabla, algo esencial cuando la tabla de hechos crece a millones de filas.

CREATE INDEX IX_FactVendas_Data
    ON FactVendas (DataKey);

CREATE INDEX IX_FactVendas_Produto
    ON FactVendas (ProdutoKey);

Verificar el resultado

Para confirmar que la carga salió bien, cuenta las filas y valida que todas las claves tienen correspondencia en las dimensiones. Una tabla de hechos sana no tiene claves huérfanas:

SELECT COUNT(*) AS TotalLinhas,
       SUM(ValorVenda) AS TotalVendido
FROM   FactVendas;

-- Procurar chaves sem dimensao (deve devolver 0 linhas)
SELECT f.VendaID
FROM   FactVendas f
LEFT JOIN DimProduto p ON p.ProdutoKey = f.ProdutoKey
WHERE  p.ProdutoKey IS NULL;

Si la segunda consulta no devuelve filas, todas las ventas apuntan a un producto válido.

Conclusión

Has creado una tabla de hechos vinculada a las dimensiones mediante claves y lista para alimentar informes en Power BI o cualquier herramienta de BI. El siguiente paso natural es automatizar la carga con un proceso ETL y vigilar el grano a medida que llegan nuevas fuentes. ¿Cuál será la primera medida que tu equipo querrá analizar?