La idea
Un modelo de Power BI no es una tabla enorme. Es un puñado de tablas pequeñas unidas por relaciones, y la forma que mejor funciona tiene nombre: el esquema en estrella.
En el centro hay una tabla de hechos. Tiene una fila por cada cosa que ocurrió: una línea de
pedido, un clic, un pago. Sus columnas son sobre todo números que sumas (line_total,
quantity) y ids que dicen quién, qué y cuándo. Alrededor están las tablas de dimensiones.
Una dimensión tiene una fila por cada producto, cliente o día, y sus columnas son las palabras
por las que agrupas y filtras: category, state, Year.
Dibújalo y parece una estrella: los hechos en el centro y una dimensión en cada punta.
Figura 1
Una tabla plana frente a un modelo de tablas pequeñas
| order_item_id | first_name | state | product | line_total |
|---|---|---|---|---|
| 1 | Jasmine | MA | Bramble Ceramic Floor Lamp | 287.91 |
| 2 | Jasmine | MA | Vale Enamel Bowl Set | 35.97 |
| 3 | Paul | AZ | Vale Enamel Bowl Set | 47.96 |
| 4 | Paul | AZ | Chester Brass Wall Mirror | 149.00 |
| order_item_id | order_id | product_id | line_total |
|---|---|---|---|
| 1 | 1001 | 121 | 287.91 |
| 2 | 1001 | 154 | 35.97 |
| 3 | 1002 | 154 | 47.96 |
| 4 | 1002 | 194 | 149.00 |
| order_id | customer_id |
|---|---|
| 1001 | 125 |
| 1002 | 156 |
| customer_id | first_name | state |
|---|---|---|
| 125 | Jasmine | MA |
| 156 | Paul | AZ |
- Una tabla plana: una fila por línea de pedido, con los datos del cliente copiados en cada línea.
- Jasmine aparece en dos filas y Paul en otras dos. Contar las filas da cuatro clientes y son dos. Si cambias un estado, tienes que cambiarlo en cada línea.
- Sepárala.
order_itemsguarda solo los números y los ids. Cada cliente se escribe una vez encustomers, yordersdice quién compró qué. - Ahora
COUNTROWS(customers)da 2, el estado vive en un solo sitio ySUM(order_items[line_total])sigue sumando 520.84.
Por qué existe
Podrías guardarlo todo en una tabla plana, como una exportación de hoja de cálculo. Con un archivo pequeño funciona. Después los problemas se acumulan.
- Texto repetido. El nombre y el estado de Jasmine se copian en cada línea que compró. Si corriges su estado, tienes que corregirlo en cada fila, o el informe muestra dos Jasmines.
- Cuentas erróneas. Cuenta las filas de una tabla plana y contarás líneas, no clientes. Cada recuento de distintos se convierte en un apaño.
- Tamaño. Power BI comprime las columnas, pero un millón de líneas con el nombre del producto copiado sigue siendo un millón de copias. Las tablas pequeñas se recorren y se actualizan más rápido.
- Un solo sitio donde segmentar. Una única columna
Yearen la dimensión sirve a todas las medidas. En una tabla plana cada hecho necesitaría su propia columna de fecha.
La estrella escribe cada dato una sola vez. Por eso una medida como SUM(order_items[line_total]) puede
responder "por categoría", "por estado" y "por mes" sin cambiar un solo carácter.
Cómo funciona por dentro
Claves
Las tablas se encuentran mediante claves. Una clave principal es una columna con valores
únicos: customers[customer_id] tiene exactamente una fila por cliente. Una clave externa es
una columna de otra tabla que repite esos valores para apuntar a una fila: orders[customer_id].
Power BI no te pide declararlas. Eliges las dos columnas al dibujar la relación y comprueba que
el lado 1 sea realmente único.
Relaciones de uno a varios
Una relación une una clave con una clave externa. Un cliente tiene muchos pedidos, un pedido tiene muchas líneas, un producto aparece en muchas líneas, un día reúne muchos pedidos. Cada una es de uno a varios: el lado 1 es la dimensión y el lado muchos (*) es la tabla que apunta a ella.
Las dibujas en la Model view (el tercer icono de la barra izquierda de Power BI Desktop): arrastra una columna sobre otra, o usa Home → Manage relationships → New. El cuadro pide las dos columnas, la cardinalidad y la dirección del filtro cruzado.
Figura 2
La estrella de Harbor & Pine: una tabla de hechos y las descripciones alrededor
'Date'
- Date
- Year
- Month
orders
- order_id
- customer_id
- order_date
- channel
customers
- customer_id
- segment
- state
products
- product_id
- category
- unit_price
order_items
- order_item_id
- order_id
- product_id
- line_total
order_itemses la tabla de hechos: una fila por línea de pedido, con los números (line_total) y los ids que apuntan a otras tablas. Es, con diferencia, la más larga.products,customersy'Date'son dimensiones: una fila por producto, cliente o día, llenas de las palabras por las que segmentas.- Cada línea tiene un 1 en un extremo y un * en el otro. El lado 1 es la tabla que guarda la clave una sola vez; el lado * tiene muchas filas que apuntan a ella.
orderses una pequeña tabla de cabecera entre las líneas, el cliente y el calendario. La forma sigue siendo una estrella: cada descripción está a un salto corto de los números.
Dirección del filtro
Una relación no es solo una línea. Es una tubería que lleva filtros, y en una estrella normal los
lleva en un solo sentido: del lado 1 al lado muchos. Elige MA en una segmentación de estado y el
filtro llega a customers, luego a orders y luego a order_items. La suma corre entonces solo
sobre las líneas de MA.
Figura 3
Una segmentación por estado: el filtro corre en un solo sentido
'Date'
- Date
- Year
- Month
orders
- order_id
- customer_id
- order_date
- channel
customers
- customer_id
- segment
- state
state = "MA"
products
- product_id
- category
- unit_price
order_items
- order_item_id
- order_id
- product_id
- line_total
- Una segmentación elige
state = "MA". El filtro cae encustomers, la tabla dueña de esa columna. - Corre del lado 1 al lado *: primero a
ordersy luego aorder_items. Solo quedan las líneas de Massachusetts para sumar. - No sube de vuelta.
productsqueda intacta, así que una segmentación de categoría sigue mostrando todas las categorías, incluso las que MA nunca compró.
Ese flujo en un solo sentido es una virtud. Hace que una medida lea la tabla de hechos siempre por un camino predecible, y que una segmentación sobre una dimensión nunca tenga dos formas de llegar a los números. El cuadro también ofrece la dirección Both. No la toques hasta que sepas decir qué camino sigue cada filtro: dos caminos entre las mismas tablas vuelven el modelo ambiguo, y Power BI lo rechaza o elige uno por ti.
Qué va dónde
Cuando encuentres una columna nueva, hazte una pregunta: ¿la sumo o agrupo por ella? Si la
sumas, pertenece a un hecho (line_total). Si agrupas por ella, pertenece a una dimensión
(category, state, Month). Una columna que es etiqueta y número a la vez, como unit_price,
suele ser un atributo de la dimensión: describe el producto, aunque un hecho guarde el precio
realmente cobrado.
Por qué el calendario es una tabla aparte
orders[order_date] ya tiene una fecha, ¿entonces para qué una tabla 'Date'? Porque un hecho
solo tiene los días en que pasó algo, y una dimensión puede tener todos los días, con Year,
Quarter y Month listos para agrupar. Un solo calendario sirve entonces a todas las tablas de
hechos con fecha. El capítulo de inteligencia de tiempo se apoya en él.
Cuando una clave no encuentra pareja
Si un pedido apunta a un id de cliente que customers no tiene, Power BI conserva el pedido y lo
archiva en una fila en blanco del lado de la dimensión. Un (Blank) visible en una matriz suele
significar una clave externa sin pareja. Revisa las claves antes de culpar a la medida.
Errores comunes
"Una tabla grande es más simple, así que debe ser mejor"
Es más simple de mirar y más difícil de usar. La primera vez que necesites clientes distintos, una segunda fecha o un nombre de producto corregido, la tabla plana empieza a costarte. Separar una vez, al principio, es la versión barata de ese trabajo.
"Una segmentación filtra toda tabla que comparta el nombre de una columna"
Los nombres de columna no significan nada para el motor. Solo las relaciones llevan filtros. Dos
tablas con un customer_id y sin relación entre ellas se ignoran, y una segmentación sobre una
nunca toca la otra. Si un visual no reacciona a una segmentación, abre Model view y busca
la línea.
"Los filtros viajan en ambos sentidos por una relación"
No por defecto. Van del lado 1 al lado muchos. Un filtro sobre products reduce las líneas, no
customers, y un filtro sobre order_items no encoge las listas de otras tablas. Esa asimetría
es la razón por la que las dimensiones van en el lado 1 y los números en el lado muchos.
Ponte a prueba
Una pregunta. Al responderla, la lección queda marcada en el mapa; nunca bloquea un nivel.
Correcto. Un cliente es una sola fila en customers, pero hace muchos pedidos, así que el id se repite en orders. Un cliente, muchos pedidos es justo uno a varios.
No del todo. Solo el lado 1 tiene que ser único. Una clave única en ambos lados sería una relación uno a uno, y un cliente y sus pedidos no lo son.Prueba otra respuesta.
No del todo. Es al revés: customers[customer_id] es la clave de customers, y orders[customer_id] es la clave externa que apunta a ella.Prueba otra respuesta.
No del todo. Los filtros van del lado 1 al lado *, así que un filtro de customers llega a orders. Un filtro de orders no sube hasta customers en una estrella estándar.Prueba otra respuesta.
Lección hecha: ya está marcada en el mapa.