Bridge table: modelar muchos-a-muchos en star schema
Cuando un cliente puede tener varias cuentas y la misma cuenta puede pertenecer a varios clientes, el modelo en estrella clásico se queda corto: enlazar las dos dimensiones directamente crea una relación muchos-a-muchos que provoca doble conteo en las sumas y socava la fiabilidad de los informes. La respuesta didáctica y probada por la metodología Kimball es la bridge table (tabla puente), que conecta las dos dimensiones y reparte los valores con un factor de peso. A continuación creamos una, paso a paso, en SQL, y mostramos cómo consultarla sin inflar los totales.
Requisitos previos
- Un SGBD relacional (los ejemplos usan SQL Server, pero el patrón se aplica a cualquier motor).
- Un star schema con, al menos, una tabla de hechos y dos dimensiones.
- Conocimientos básicos de
CREATE TABLE,INSERTyJOIN.
Paso 1: Entender el problema muchos-a-muchos
Imagine un banco: la cuenta C-100 es una cuenta conjunta de Ana y Bruno. Si enlaza la dimensión de cuentas directamente con la dimensión de clientes y suma el saldo por cliente, el saldo de 1000 € de la cuenta C-100 cuenta 1000 € para Ana y 1000 € para Bruno — un total de 2000 € que no existe. Este es el error clásico de doble conteo, y ocurre porque la misma fila de hechos es leída por varios clientes. La bridge table lo resuelve al registrar, para cada par cuenta–cliente, qué fracción del valor pertenece a cada uno.
Paso 2: Crear las dimensiones
Empezamos con dos dimensiones sencillas. Cada una tiene su propia clave sustituta (surrogate key), la columna por la que se conectarán la bridge table y los hechos.
CREATE TABLE DimCliente (
cliente_key INT PRIMARY KEY,
nome VARCHAR(100)
);
CREATE TABLE DimConta (
conta_key INT PRIMARY KEY,
numero_conta VARCHAR(20),
tipo VARCHAR(30)
);
Paso 3: Crear la bridge table
La tabla puente tiene una fila por cada par cuenta–cliente. La columna fator_peso es el corazón del patrón: guarda la fracción del valor que pertenece a cada cliente. Colocamos el peso en la tabla puente, y no en la tabla de hechos, para que la misma fila de hechos pueda leerse de varias formas sin duplicarse. Para una cuenta con dos titulares, cada fila recibe 0,5.
CREATE TABLE PonteContaCliente (
conta_key INT NOT NULL,
cliente_key INT NOT NULL,
fator_peso DECIMAL(9,4) NOT NULL,
CONSTRAINT PK_Ponte PRIMARY KEY (conta_key, cliente_key)
);
Regla de oro: la suma de los fator_peso de una misma cuenta debe dar siempre 1,0. Eso es lo que garantiza que los totales cuadren.
Paso 4: Poblar la tabla puente con el factor de peso
La cuenta conjunta C-100 (conta_key 1) tiene dos titulares, por lo que cada uno se lleva 0,5. La cuenta individual C-200 (conta_key 2) tiene un solo titular, con factor 1,0. Observe cómo, en cada cuenta, los factores suman exactamente 1,0.
INSERT INTO PonteContaCliente (conta_key, cliente_key, fator_peso) VALUES
(1, 10, 0.5), -- C-100: Ana
(1, 20, 0.5), -- C-100: Bruno
(2, 10, 1.0); -- C-200: Ana
Paso 5: Consultar a través de la bridge table
La tabla de hechos FactSaldo guarda el saldo a nivel de cuenta (un registro por cuenta). Para obtener el saldo por cliente sin doble conteo, atravesamos la puente y multiplicamos el saldo por el fator_peso.
SELECT
c.nome,
SUM(f.saldo * p.fator_peso) AS saldo_atribuido
FROM FactSaldo AS f
JOIN PonteContaCliente AS p ON p.conta_key = f.conta_key
JOIN DimCliente AS c ON c.cliente_key = p.cliente_key
GROUP BY c.nome;
La gran ventaja es la flexibilidad: si, en lugar del valor repartido, quiere conocer el saldo total de las cuentas a las que cada cliente tiene acceso, basta con quitar el fator_peso de la suma. El mismo modelo responde a las dos preguntas — cuánto pertenece a cada uno y a qué valores accede cada uno.
Verificar el resultado
Con un saldo de 1000 € en C-100 y 500 € en C-200, la consulta ponderada devuelve Ana = 1000 € (500 de C-100 más 500 de C-200) y Bruno = 500 €. La suma total es 1500 €, exactamente el saldo real del banco — sin inflación. Si los números no cuadran, verifique primero si los fator_peso de cada cuenta suman 1,0; casi siempre es ahí donde está el error.
Conclusión
Con una bridge table y un factor de peso, ha resuelto una relación muchos-a-muchos sin perder el detalle ni inflar los totales — la base de informes en los que se puede confiar. El siguiente paso es aplicar el mismo patrón a otros casos, como productos con varias categorías o proyectos con varios equipos, decidiendo caso por caso cuándo usar la suma ponderada. ¿Qué relación muchos-a-muchos en su modelo está esperando un puente?