Power BI e la Gestione delle Relazioni

Potrebbe interessarti:

Se vuoi imparare a preparare, modellare, visualizzare e analizzare i dati aziendali in modo efficace, dai un’occhiata al corso Introduzione a Power BI, e al Corso Avanzato Power BI DAX.

Dimmi di Più

Nei post sui Database Relazionali e la Modellazione Dimensionale, abbiamo introdotto i principi fondamentali della creazione e gestione dei modelli relazionali, analizzando la struttura tipica di un database relazionale transazionale e confrontandola con quella di uno Star Schema.

Abbiamo visto come entrambi i modelli presentino punti di forza e limiti specifici, a seconda del contesto in cui vengono utilizzati: l’uno più adatto alle operazioni quotidiane (OLTP), l’altro pensato per l’analisi e la sintesi dei dati.

In questo articolo riprendiamo il tema della gestione delle relazioni tra tabelle, ma lo analizziamo dal punto di vista di Power BI, ossia in un contesto di modellazione dati orientato all’analisi, dove le relazioni assumono un ruolo logico e funzionale alla propagazione dei filtri e al calcolo delle misure, più che al mantenimento dell’integrità referenziale.

Le Relazioni tra Tabelle

Le regole che governano le relazioni tra tabelle in Power BI sono in parte simili a quelle utilizzate nei tradizionali database relazionali, ma presentano anche differenze sostanziali dovute alla diversa finalità dei due sistemi.

In Power BI, una relazione definisce il modo in cui tabelle diverse del modello dati sono collegate tra loro. Le relazioni permettono al motore di Power BI di collegare informazioni provenienti da più tabelle, consentendo di creare visualizzazioni e calcoli che combinano dati di origine differente.

Le relazioni di Power BI propagano i filtri applicati a una tabella verso le altre tabelle collegate, in base al percorso delle relazioni definite nel modello. Questa propagazione avviene automaticamente finché esiste un cammino di relazione attivo da seguire, e può quindi estendersi a più tabelle collegate in cascata.

A differenza di quanto avviene in un database relazionale tradizionale, in Power BI le relazioni non garantiscono l’integrità referenziale dei dati. Ciò significa che Power BI non verifica che i valori di chiave corrispondano sempre tra tabelle correlate: è compito del progettista assicurarsi che i dati siano coerenti.

Quando si applicano più filtri contemporaneamente a una tabella, Power BI combina tali condizioni con un operatore logico AND, restituendo solo le righe che soddisfano tutti i criteri.

Infine, una relazione del modello collega una colonna di una tabella con una colonna di un’altra tabella distinta. Non è possibile, infatti, creare una relazione tra due colonne appartenenti alla stessa tabella: per collegare dati interni a una stessa entità si utilizzano invece altre tecniche, come le funzioni DAX o tabelle derivate.

In sintesi, nei database relazionali, le relazioni servono principalmente a garantire la coerenza e l’integrità dei dati tramite vincoli tra chiavi primarie e chiavi esterne. In Power BI, invece, le relazioni hanno uno scopo logico e analitico: vengono usate per collegare le tabelle del modello, consentendo al motore di analisi di propagare filtri e contesti di calcolo durante l’elaborazione delle misure DAX e la creazione dei report.

Tipi di Relazione

Similmente a quanto accade nei database relazionali, anche in Power BI esistono tre tipi principali di relazioni, che si distingono per la loro cardinalità1. Questi tre tipi di relazione sono: “Uno a Uno”, “Uno a Molti” e “Molti a Molti”. In Power BI, la cardinalità delle relazioni è un concetto fondamentale, perché determina come i filtri si propagano da una tabella all’altra.

Relazione “Uno a Molti”

Nelle relazioni con cardinalità “Uno a Molti” (“One to Many”, o “1:*”), un record della prima tabella può essere collegato a più record della seconda, mentre ciascun record della seconda si collega a un solo record della prima. Ad esempio, un prodotto può essere associato a uno o più ordini, e più ordini possono referenziare lo stesso prodotto. Questo tipo di relazione descrive la direzionalità tra una Dimension Table (lato “Uno”) e la relativa Fact Table (lato “Molti”):

Diagramma della Cardinalità 'Uno a Molti'
Figura 1: Cardinalità ‘Uno a Molti’

Questa è la cardinalità più comune di Power BI, e dovrebbe essere utilizzata la maggior parte delle volte. Il valore di cardinalità “Uno” deve sempre provenire dalla Dimension Table, mentre “Molti” deve essere sempre sul lato della Fact Table. Questo indica che la Fact table viene filtrata o segmentata tramite il filtro generato dalla selezione dei campi della Dimension table. Inoltre, la direzione del filtro dovrebbe sempre andare dalla Dimension table alla Fact table.

Relazione “Uno a Uno”

La relazione con cardinalità “Uno a Uno” (“One to One”, o “1:1”) è un tipo di relazione in cui ciascun valore appare al massimo una volta in entrambe le tabelle. In altre parole, se due tabelle sono collegate con una relazione “Uno a Uno”, significa che una rappresenta semplicemente un’estensione dell’altra, aggiungendo ulteriori colonne allo stesso insieme di righe.

In Power BI, questo tipo di relazione non è consigliata, perché memorizza informazioni ridondanti, e suggerisce che il modello non è stato progettato correttamente.

Vediamo un semplice esempio. Nell’immagine seguente, la tabella Product contiene i campi che descrivono il nome del prodotto e il suo fornitore. La tabella Price definisce il prezzo del prodotto:

Diagramma della Cardinalità 'Uno a Uno'
Figura 2: Cardinalità ‘Uno a Uno’

È chiaro che il campo Price dovrebbe far parte della tabella Product, e che la tabella Price non ha motivo di esistere nel Data Model, risultando di fatto superflua. Il modo più efficace per eliminare questa relazione è utilizzare, in Power BI, la funzione Merge del Power Query Editor, così da combinare le due tabelle in un’unica query:

Dialog di Power BI per l'operazione di Merge di due tabelle 'Uno a Uno'
Figura 3: Operazione di Merge di due tabelle ‘Uno a Uno’

La tabella risultante da tale operazione avrà i campi di entrambe le tabelle precedenti, in questo caso: Product, Vendor e Price:

Tabella risultante dopo l'operazione di Merge delle due tabelle in relazione 'Uno a Uno'
Figura 4: Tabella risultante dopo l’operazione di Merge

Relazione “Molti a Molti”

Una relazione “Molti a Molti” (“Many to Many “, o “*:*”) si verifica quando più righe di una tabella sono associate a più righe di un’altra tabella. In Power BI, per capire come implementare questo tipo di relazione, dobbiamo distinguere due casi principali:

  • “Molti a Molti” tra Dimension Table;
  • “Molti a Molti” tra Fact Table.

Vediamo di seguito entrambe le circostanze.

“Molti a Molti” tra Dimension Table

Consideriamo una tabella SalesPerson (venditore) e una tabella Region. Un venditore può gestire una particolare regione, e in una regione possono operare più venditori. Questa è una relazione logica “Many to Many” tra entità descrittive, e può essere rappresentata dal diagramma seguente:

Diagramma della Relazione 'Molti a Molti' tra Dimension Table
Figura 5: Relazione ‘Molti a Molti’ tra Dimension Table

In questo caso, per implementare una relazione “Molti a Molti”, dobbiamo creare una bridge table (tabella ponte) — chiamata anche “fact-less fact table” — che contiene le combinazioni reali tra le chiavi delle due tabelle che si vogliono mettere in relazione tra loro. Ad esempio:

Tabella Ponte usata per implementare la relazione 'Molti a Molti'
Figura 6: Tabella Ponte usata per implementare la relazione ‘Molti a Molti’

La tabella SalespersonRegion funge da bridge table con chiave composta: una struttura simile a quella utilizzata nei database OLTP, ma impiegata qui con finalità analitiche, non transazionali. SalespersonRegion non deve essere interpretata come una Dimension Table aggiuntiva. Si tratta invece di una tabella di servizio, una “fact-less fact table”, ovvero una tabella priva di misure: non contiene valori numerici di business destinati all’aggregazione, ma fornisce solo i riferimenti necessari a collegare le due tabelle dimensionali.

SalespersonRegion è infatti costituita da sole due colonne chiave esterne — una verso SalesPerson, e una verso Region. Questa struttura consente di filtrare e correlare le due dimensioni in modo chiaro, controllato e senza ambiguità, perché rispetta i principi dello Star Schema.

“Molti a Molti” tra Fact Table

Dal 2018, Power BI supporta nativamente le relazioni di tipo “Many to Many” . Ciò significa che, se due tabelle contengono chiavi non univoche, Power BI può creare ugualmente una relazione diretta tra di esse, — senza usare una tabella ponte — lasciando che sia il motore di calcolo a gestire automaticamente un join virtuale per la propagazione dei filtri.

Nell’immagine seguente, la tabella Manufacturing contiene i costi di produzione di alcuni prodotti, mentre la tabella Sales contiene i relativi dati di vendita. Le due tabelle sono unite tra loro mediante una relazione “Molti a Molti” nativa, usando i campi Product di entrambe:

Diagramma della Relazione 'Molti a Molti'
Figura 7: Relazione ‘Molti a Molti’

I dati delle due tabelle sono mostrati di seguito. Come possiamo notare, entrambe le colonne Manufacturing[Product] e Sales[Product] hanno valori ripetuti, condizione necessaria per creare tale relazione:

Dati delle due tabelle 'Manufacturing' e 'Sales'
Figura 8: Dati delle due tabelle Manufacturing e Sales

Questa funzionalità è utile per modelli semplici o per casi “inevitabili”, ma può causare diversi problemi. In una relazione classica “Uno a Molti”, il flusso dei filtri è chiaro e unidirezionale: parte dalla Dimension Table (lato “Uno”) che ha valori univoci, e raggiunge la Fact Table (lato “Molti”) con valori duplicati.

In una relazione “Molti a Molti”, questo meccanismo viene meno, poiché non esiste un “lato Uno”. Perciò Power BI forza automaticamente una relazione bidirezionale, con la proprietà “Cross Filter Direction” settata a “Both”, per far sì che i filtri della Tabella A si applichino alla Tabella B, e viceversa.

Questo scenario introduce diversi problemi, tra cui l’ambiguità nella propagazione dei filtri e la creazione di un vero e proprio prodotto cartesiano2 tra le righe filtrate delle due tabelle. Tali situazioni possono generare comportamenti imprevedibili, compromettere la correttezza dei calcoli e, in molti casi, incidere negativamente anche sulle performance complessive di Power BI.

In Power BI, le relazioni “Molti a Molti” non sono vietate, ma vanno utilizzate solo quando inevitabili, e con una chiara comprensione dei loro effetti. Per risolvere questi problemi, la documentazione Microsoft raccomanda di evitare le relazioni “Many to Many” dirette tra Fact Table, e di ricondurre il modello a uno Star Schema correttamente strutturato. In pratica, le Fact Table devono essere collegate tra loro indirettamente, attraverso delle Dimension Table condivise. Queste dimensioni — come Customer, Product, Date o altre entità di contesto — introducono chiavi univoche e permettono di scomporre la relazione “Molti a Molti” in due relazioni “Uno a Molti”, rendendo il modello più stabile, leggibile e coerente.

Consideriamo nuovamente le tabelle Manifacturing e Sales viste precedentemente. Creiamo una nuova tabella Date, con questo comando DAX:

// Calculated Table
Date =
    ADDCOLUMNS(
        CALENDARAUTO(),
        "Year", YEAR ([Date]),
        "Year-Month", FORMAT([Date],"YYYY/MM"),
        "Year-Quarter", FORMAT([Date],"YYYY/\QQ"),
        "Month", FORMAT([Date], "mmmm"),
        "Month Number", MONTH([Date]),
        "Quarter", FORMAT([Date], "\QQ")
    )

Poi, estraiamo dalle colonne Manufacturing[Product] e Sales[Product] i relativi valori, li salviamo in una nuova tabella Product con un unico campo Product, e applichiamo una rimozione dei valori duplicati. Possiamo farlo con DAX in questo modo:

// Calculated Table
Product =
    // return a one column table that contains the unique values in that column
    DISTINCT(
        // get a table that contains all the rows
        // from each of the table expressions
        UNION(
            VALUES(Manufacturing[Product]),  // Table Expression #1
            VALUES(Sales[Product])           // Table Expression #2
        )
    )

Quello che otteniamo è una tabella con un unico campo, con la lista dei valori distinti presenti in Manufacturing[Product] e Sales[Product]. Ad esempio:

Valori distinti della tabella 'Product'
Figura 9: Valori distinti della tabella Product

Ora, con le due nuove tabelle Date e Product, possiamo eliminare la relazione “Molti a Molti” — causa dei nostri problemi — e creare una relazione “One to Many” per ogni coppia (Dimension Table, Fact Table), come mostrato di seguito:

Diagramma della Relazione 'Molti a Molti' tra Fact Table
Figura 10: Relazione ‘Molti a Molti’ tra Fact Table

Con un data model di questo tipo, possiamo filtrare i dati “in sicurezza”, utilizzando i campi Product[Product] e Date[Date] delle relative tabelle dimensionali:

Reportistica che mostra l'applicazione della relazione 'Molti a Molti' tra Fact Table
Figura 11: Applicazione della relazione ‘Molti a Molti’ tra Fact Table

Cross-Filter Direction

In Power BI, ogni relazione possiede una proprietà chiamata “Cross-Filter Direction”, che stabilisce in quale direzione si propaga il filtro tra le due tabelle collegate. Si tratta di un comportamento specifico di Power BI (e, più in generale, dei modelli tabulari), non presente nei database relazionali tradizionali, dove le relazioni non hanno una direzione di filtro implicita. Le opzioni disponibili sono due:

  • “Single”: indica una direzione singola di propagazione del filtro.
  • “Both”: indica che il filtro può propagarsi in entrambe le direzioni.

Quando una relazione permette al filtro di fluire in entrambi i sensi, viene definita bidirezionale.

Questa proprietà è rappresentata graficamente nel Model View da una piccola punta di freccia posta al centro della linea che unisce le due tabelle. Nell’esempio riportato in Figura 12, la tabella DimCustomer è collegata a FactInternetSales tramite una relazione “Uno a Molti” con direzione singola: il filtro scorre dalla Dimension Table verso la Fact Table, come previsto nel classico schema a stella.

Al contrario, tra FactInternetSales e DimProduct la relazione è impostata con direzione del filtro in entrambe le direzioni (“Both”), per cui il filtro può propagarsi da una tabella all’altra senza limitazioni:

Diagramma che indica due relazioni con Cross Filter Direction singola e doppia
Figura 12: relazioni con Cross Filter Direction singola e doppia

Cross-Filter Direction Singola

Quando una relazione ha l’attributo Cross-Filter Direction impostato su “single”, significa che solo una delle due tabelle può propagare i filtri verso l’altra. La direzione del filtro è quindi unidirezionale.

Ricollegandoci allo schema a stella, nelle relazioni “Uno a Molti” la direzione del filtro parte normalmente dal lato “Uno” (la Dimension Table) e raggiunge il lato “Molti” (la Fact Table). Questa è la configurazione predefinita adottata da Power BI per collegare una tabella dimensionale a una tabella dei fatti. In tale scenario, ogni volta che l’utente seleziona o filtra un attributo della Dimension Table (ad esempio un prodotto, un cliente o una data), la Fact Table viene automaticamente filtrata per mostrare solo i record coerenti con quella selezione. In altre parole, sono i valori descrittivi della Dimension Table a determinare quali fatti devono essere considerati dal report.

Diagramma che indica due relazioni con Cross Filter Direction singola
Figura 13: relazioni con Cross Filter Direction singola

Nell’immagine precedente, entrambe le Dimension Table sono collegate alla Fact Table tramite relazioni con Cross-Filter Direction impostato su “single”. Questo significa che la propagazione del filtro avviene solo dalla Dimension Table verso la Fact Table. In pratica:

  • DimCustomer può filtrare FactInternetSales;
  • DimProduct può filtrare FactInternetSales;
  • ma DimCustomer non può filtrare DimProduct (e viceversa) utilizzando FactInternetSales come tabella ponte.

Il motivo è che la relazione tra FactInternetSales e DimProduct non consente al filtro di risalire verso la Dimension Table. La direzione è unidirezionale, quindi il filtro si ferma alla Fact Table, e non può propagarsi oltre. Di conseguenza, anche se le due tabelle dimensionali sono collegate alla stessa Fact Table, non possono filtrarsi reciprocamente.

Cross-Filter Direction Doppia

Quando una relazione tra due tabelle è configurata con “Cross-Filter Direction” = “Both”, la propagazione dei filtri può avvenire in entrambi i sensi. Ciò significa che ciascuna delle due tabelle può filtrare l’altra, creando un canale di comunicazione bidirezionale. Considerando la Figura 12, possiamo osservare che:

  • la tabella DimProduct può filtrare FactInternetSales;
  • la tabella FactInternetSales può filtrare DimProduct;
  • inoltre, anche DimCustomer può arrivare a filtrare DimProduct, utilizzando FactInternetSales come tabella ponte.

Quest’ultimo punto è particolarmente importante: i filtri applicati su DimCustomer si propagano verso la Fact Table e, grazie alla bidirezionalità, possono continuare il loro percorso verso DimProduct. In altre parole, la relazione in modalità “both” permette ai filtri di attraversare più tabelle, raggiungendo anche quelle dimensioni che altrimenti sarebbero isolate in una configurazione a direzione singola.

Power BI e l’Integrità Referenziale

Nei database relazionali (ad esempio SQL Server), le relazioni tra colonne Primary Key (PK) e Foreign Key (FK) vengono implementate tramite vincoli di integrità referenziale. Questo significa che il motore del database impedisce l’inserimento di record “orfani”, ossia righe che contengono un valore di chiave esterna (FK) non presente come chiave primaria (PK) nella tabella di riferimento. In questo modo, il sistema garantisce che i dati siano sempre coerenti e che ogni collegamento tra tabelle sia valido.

Diagramma che mostra l'Integrità Referenziale tra due tabelle
Figura 12: Integrità Referenziale tra due tabelle

In Power BI, invece, il modello dati tabulare non applica vincoli di integrità referenziale tra PK e FK. Le relazioni definite nel modello hanno uno scopo puramente logico e analitico, e servono principalmente a propagare i filtri e a trasferire il contesto di calcolo tra tabelle durante l’esecuzione delle formule DAX. Power BI non verifica la corrispondenza tra chiavi per diversi motivi:

  • Prestazioni:
    controllare e validare vincoli FK/PK a ogni caricamento o aggiornamento dei dati sarebbe un’operazione molto costosa e rallenterebbe il processo di refresh.

  • Natura dei dati analitici:
    nei sistemi di tipo analitico o di reporting, i dati provenienti da fonti eterogenee non sono sempre perfettamente coerenti. L’applicazione di vincoli rigidi potrebbe bloccare il caricamento del modello nel caso in cui, ad esempio, mancasse un valore corrispondente in una tabella dimensionale.

  • Obiettivo funzionale:
    in Power BI, le relazioni servono per la propagazione del Filter Context, e non per assicurare la coerenza fisica dei dati, che rimane responsabilità dei processi di preparazione e modellazione a monte (ETL o data warehouse).


  1. La cardinalità indica quale indica quanti elementi di una tabella possono essere associati a quanti elementi dell’altra — cioè il “numero massimo” di corrispondenze possibili. ↩︎

  2. Il prodotto cartesiano generato in una relazione Many-to-Many è equivalente a una cross join tra i record filtrati delle due tabelle. Questo è il motivo per cui si possono avere duplicazioni, somme gonfiate e risultati inattesi nei calcoli. ↩︎