Como criar uma bridge table num Data Warehouse
Uma bridge table (tabela ponte) é a forma correta de representar uma relação muitos-para-muitos num data warehouse em esquema em estrela, sem duplicar valores nem inflacionar os totais. O exemplo clássico é uma conta bancária que pertence a vários clientes: se ligar a conta diretamente a cada cliente, o saldo é contado tantas vezes quantos os titulares. A solução é uma tabela intermédia com um fator de peso que reparte cada valor de forma justa.
Pré-requisitos
- Um servidor de base de dados relacional (os exemplos usam SQL Server / T-SQL, mas adaptam-se a qualquer motor).
- Um data warehouse com, pelo menos, uma tabela de factos e uma dimensão em esquema em estrela.
- Conhecimentos básicos de SQL:
CREATE TABLE,INSERTeJOIN.
Passo 1: Perceber o problema muitos-para-muitos
Imagine uma tabela de factos fact_saldo_diario ao grão de conta: cada linha guarda o saldo de uma conta num dia. O problema aparece quando uma conta tem vários titulares e quer analisar o saldo por cliente. Não pode colocar o cliente na dimensão da conta (a conta teria de se repetir por cada titular), nem duplicar a linha de facto (o saldo passaria a ser somado várias vezes). A bridge table resolve isto ao ficar entre a conta e o cliente, guardando cada par conta–cliente numa linha.
Passo 2: Criar as dimensões e a bridge table
Crie primeiro a dimensão de clientes e a dimensão de contas, ambas com chaves substitutas. Depois crie a bridge table, que liga as duas e inclui a coluna fator_peso — a fração do valor que cabe a cada titular.
CREATE TABLE dim_cliente (
cliente_sk INT IDENTITY(1,1) PRIMARY KEY,
nome VARCHAR(100)
);
CREATE TABLE dim_conta (
conta_sk INT IDENTITY(1,1) PRIMARY KEY,
numero_conta VARCHAR(20)
);
CREATE TABLE bridge_conta_cliente (
conta_sk INT NOT NULL REFERENCES dim_conta(conta_sk),
cliente_sk INT NOT NULL REFERENCES dim_cliente(cliente_sk),
fator_peso DECIMAL(5,4) NOT NULL,
CONSTRAINT pk_bridge PRIMARY KEY (conta_sk, cliente_sk)
);
A chave primária composta (conta_sk, cliente_sk) impede pares repetidos e garante que cada titular aparece uma só vez por conta.
Passo 3: Preencher a bridge com o fator de peso
A regra de ouro é simples: para cada conta, a soma dos fator_peso dos seus titulares tem de dar 1. Uma conta com dois titulares reparte o saldo em 0,5 + 0,5; com um único titular, o peso é 1. O exemplo seguinte assume que a conta 1 tem dois titulares e a conta 2 tem apenas um.
INSERT INTO bridge_conta_cliente (conta_sk, cliente_sk, fator_peso) VALUES
(1, 10, 0.5), -- conta 1, titular 10
(1, 11, 0.5), -- conta 1, titular 11
(2, 12, 1.0); -- conta 2, titular unico
O fator_peso também é conhecido por allocation factor. Guardá-lo na bridge, e não na consulta, garante que todos aplicam a mesma regra de repartição.
Passo 4: Consultar os factos com o fator de peso
Para obter o saldo por cliente sem inflacionar os totais, junte a tabela de factos à bridge e, depois, à dimensão de clientes, multiplicando sempre a medida pelo fator_peso. É essa multiplicação que evita a dupla contagem.
SELECT
c.nome,
SUM(f.saldo * b.fator_peso) AS saldo_alocado
FROM fact_saldo_diario AS f
JOIN bridge_conta_cliente AS b
ON b.conta_sk = f.conta_sk
JOIN dim_cliente AS c
ON c.cliente_sk = b.cliente_sk
GROUP BY c.nome;
Verificar o resultado
Faça duas verificações rápidas. Primeiro, confirme que os pesos de cada conta somam exatamente 1 — nenhuma conta pode ficar a menos nem a mais:
SELECT conta_sk, SUM(fator_peso) AS total_peso
FROM bridge_conta_cliente
GROUP BY conta_sk
HAVING SUM(fator_peso) <> 1;
Se esta consulta não devolver linhas, todos os pesos estão corretos. Segundo, compare o total alocado por cliente (com o fator_peso) com o total original das contas: os dois valores devem ser iguais. Se baterem certo, não há dupla contagem.
Conclusão
Com uma bridge table e um fator de peso passou a analisar relações muitos-para-muitos sem empolar os totais — uma técnica essencial na modelação dimensional. A partir daqui, experimente pesos diferentes (por exemplo, um titular principal com 0,7 e um secundário com 0,3) ou acrescente datas de início e fim para tratar a bridge como uma relação que muda ao longo do tempo. E se um cliente tiver várias contas, como resolveria a análise no sentido inverso?