Linee guida per le relazioni molti-a-molti
Questo articolo è destinato a te, modellatore di dati che lavora con Power BI Desktop. Descrive tre diversi scenari di modellazione molti-a-molti. Fornisce inoltre indicazioni su come progettare con successo per loro nei tuoi modelli.
Nota
Un'introduzione alle relazioni tra modelli non è descritta in questo articolo. Se non si ha familiarità con le relazioni, le relative proprietà o come configurarle, è consigliabile leggere prima l'articolo relazioni tra modelli in Power BI Desktop.
È anche importante avere una conoscenza della progettazione dello schema a stella. Per ulteriori informazioni, vedere Comprendere lo schema a stella e la sua importanza per Power BI.
Esistono tre scenari diversi di tipo molti-a-molti. Possono verificarsi quando è necessario:
- Correlare due tabelle delle dimensioni
- Correlare due tabelle dei fatti
- Correlare tabelle dei fatti con un livello di dettaglio superiore, quando la tabella dei fatti archivia righe a un livello di dettaglio più elevato rispetto alle righe della tabella delle dimensioni
Correlare dimensioni molti-a-molti
Lo scenario classico molti a molti riguarda due entità, ad esempio i clienti e i conti bancari. Si consideri che i clienti possono avere più account e che gli account possono avere più clienti. Quando un account ha più clienti, viene comunemente chiamato titolari di conti comuni.
La modellazione di queste entità è semplice. Una tabella delle dimensioni archivia gli account e un'altra tabella delle dimensioni archivia i clienti. Come è caratteristica delle tabelle delle dimensioni, in ogni tabella è presente una colonna identificatore univoco (ID). Per modellare la relazione tra le due tabelle, è necessaria una terza tabella. Questa tabella è comunemente chiamata tabella di bridging . In questo esempio, lo scopo è archiviare una riga per ogni associazione di account cliente. È interessante notare che quando questa tabella contiene solo colonne identificative, viene chiamata tabella priva di fatti .
Ecco un diagramma semplicistico delle tre tabelle del modello.
La prima tabella è denominata Account
e contiene due colonne: AccountID
e Account
. La seconda tabella è denominata AccountCustomer
e contiene due colonne: AccountID
e CustomerID
. La terza tabella è denominata Customer
e contiene due colonne: CustomerID
e Customer
. Le relazioni non esistono tra nessuna delle tabelle.
Vengono aggiunte due relazioni uno-a-molti per correlare le tabelle. Ecco un diagramma del modello aggiornato delle tabelle correlate. È stata aggiunta una tabella dei fatti denominata Transaction
. Registra le transazioni di conto. La tabella di raccordo e tutte le colonne identificatrici sono state nascoste.
Per descrivere il funzionamento della propagazione del filtro delle relazioni, il diagramma del modello è stato modificato per visualizzare le righe della tabella.
I dettagli delle righe per le quattro tabelle sono presentati nell'elenco puntato seguente:
- La tabella
Account
ha due righe:-
AccountID
1 è per Account-01 -
AccountID
2 è Account-02
-
- La tabella
Customer
ha due righe:-
CustomerID
91 è per Customer-91 -
CustomerID
92 è per Customer-92
-
- La tabella
AccountCustomer
ha tre righe:-
AccountID
1 è associato aCustomerID
91 -
AccountID
1 è associato aCustomerID
92 -
AccountID
2 è associato aCustomerID
92
-
- La tabella
Transaction
ha tre righe:-
Date
1 gennaio 2019,AccountID
3,Amount
100 -
Date
2 febbraio 2019,AccountID
2,Amount
200 -
Date
3 marzo 2019,AccountID
1,Amount
-25
-
Vediamo cosa accade quando il modello viene interrogato.
Nell'immagine seguente, ci sono due visualizzazioni di tabella che riepilogano la colonna Amount
della tabella Transaction
. Il primo oggetto visivo raggruppa per conto, quindi la somma delle colonne Amount
rappresenta il saldo del conto . Il secondo grafico raggruppa per cliente, pertanto, la somma delle colonne Amount
rappresenta il saldo del cliente .
La prima tabella visuale (Account Balance) include due colonne: Account
e Amount
. Viene visualizzato il risultato seguente:
- importo del saldo conto-01 è 75.
- importo del saldo conto-02 è 200.
- Il totale è 275.
Il secondo visual della tabella (Customer Balance) include due colonne: Customer
e Amount
. Viene visualizzato il risultato seguente:
- L'importo del saldo cliente-91 è 275.
- l'importo del saldo Cliente-92 è 275.
- Il totale è 275.
Una rapida occhiata alle righe della tabella e alla visualizzazione del Saldo conto rivela che il risultato è corretto, per ogni conto e l'importo totale. Ciò è dovuto al fatto che ogni raggruppamento di account comporta una propagazione del filtro nella tabella Transaction
per tale account.
Tuttavia, qualcosa non sembra corretto con la visualizzazione Customer Balance. Ogni cliente in questa visualizzazione ha lo stesso saldo del saldo totale. Questo risultato potrebbe essere corretto solo se ogni cliente era un titolare congiunto di ogni conto. Questo non è il caso in questo esempio. Si è verificato un problema ed è correlato alla propagazione dei filtri. I filtri non vengono trasmessi fino alla tabella Transaction
.
Se si seguono le direzioni del filtro delle relazioni dalla tabella Customer
alla tabella Transaction
, è possibile determinare che la relazione tra le tabelle Account
e AccountCustomer
si propaga nella direzione errata. La direzione del filtro per questa relazione deve essere impostata su Both
.
Come previsto, non è stata apportata alcuna modifica alla visualizzazione del saldo del conto.
Il grafico Customer Balance ora visualizza il seguente risultato:
- Cliente-91 importo del saldo è 75.
- importo del saldo cliente-92 è 275.
- Il totale è 275.
La visualizzazione del Customer Balance ora mostra un risultato corretto. Segui le istruzioni del filtro per conto proprio e osserva come sono stati calcolati i saldi dei clienti. Comprendere anche che il totale visivo significa tutti i clienti.
Un utente che non ha familiarità con le relazioni del modello potrebbe concludere che il risultato non è corretto. Potrebbero chiedere: Perché non è il saldo totale per Customer-91
e Customer-92
uguale a 350 (75 + 275)?
La risposta alla loro domanda consiste nel comprendere la relazione molti-a-molti. Ogni saldo cliente può rappresentare l'aggiunta di più saldi del conto; pertanto, i saldi dei clienti sono non cumulativi.
Guida sul rapporto delle dimensioni molti-a-molti
Quando si dispone di una relazione molti-a-molti tra le tabelle dimensionali, seguire queste indicazioni:
- Aggiungere ogni entità correlata molti-a-molti come tabella del modello, assicurandosi che abbia una colonna ID.
- Aggiungere una tabella di collegamento per archiviare le entità associate.
- Creare relazioni uno-a-molti tra le tre tabelle.
- Impostare una relazione bidirezionale per consentire la propagazione dei filtri fino alla tabella dei fatti.
- Quando non è appropriato avere valori ID mancanti, disabilitare la proprietà
Is Nullable
. L'aggiornamento dei dati avrà esito negativo quando i valori mancanti vengono rilevati. - Nascondere la tabella di collegamento, a meno che non contenga altre colonne o misure necessarie per il reporting.
- Nascondere tutte le colonne ID non adatte per la creazione di report, ad esempio quando le colonne archiviano valori di chiave surrogata.
- Se è opportuno lasciare visibile una colonna ID, assicurarsi che si tratti del lato "uno" della relazione, nascondendo sempre la colonna laterale "molti". Ciò è dovuto al fatto che i filtri applicati all'unica diapositiva generano prestazioni di filtro migliori.
- Per evitare confusione o interpretazioni errate, comunicate le spiegazioni agli utenti del report. È possibile aggiungere descrizioni con caselle di testo o tooltip dell'intestazione visiva.
Non è consigliabile correlare direttamente le tabelle delle dimensioni molti-a-molti. Questo approccio di progettazione richiede la configurazione di una relazione con cardinalità molti-a-molti. Concettualmente può essere ottenuto, ma implica che le colonne correlate potrebbero contenere valori duplicati. È una procedura di progettazione ben accettata tuttavia, che le tabelle delle dimensioni abbiano una colonna ID. Le tabelle delle dimensioni devono usare sempre la colonna ID come lato "uno" di una relazione.
Correlare fatti in un rapporto molti a molti
Un tipo di scenario molti-a-molti diverso prevede la correlazione di due tabelle di fatti. Due tabelle dei fatti possono essere correlate direttamente. Questa tecnica di progettazione può essere utile per un'esplorazione rapida e semplice dei dati. Tuttavia, e per essere chiari, in genere non è consigliabile questo approccio di progettazione. Verrà spiegato perché più avanti in questa sezione.
Si consideri un esempio che include due tabelle dei fatti: Order
e Fulfillment
. La tabella Order
contiene una riga per riga di ordine e la tabella Fulfillment
può contenere zero o più righe per riga di ordine. Le righe nella tabella Order
rappresentano gli ordini di vendita. Le righe nella tabella Fulfillment
rappresentano gli articoli degli ordini spediti. Una relazione molti-a-molti è correlata alle colonne OrderID
in ogni tabella, con propagazione del filtro solo dalla tabella Order
(ovvero la tabella Order
filtra la tabella Fulfillment
).
La cardinalità della relazione è impostata su Many-to-many
per supportare l'archiviazione di valori duplicati della colonna OrderID
in entrambe le tabelle. Nella tabella Order
i valori ID duplicati possono esistere perché un ordine può avere più righe. Nella tabella Fulfillment
possono esistere valori ID duplicati perché gli ordini possono avere più righe e le righe degli ordini possono essere evase da diverse spedizioni.
Verranno ora esaminate le righe della tabella. Nella tabella Fulfillment
si noti che le righe degli ordini possono essere soddisfatte da più spedizioni. L'assenza di una riga di ordine indica che l'ordine è ancora da soddisfare.
I dettagli delle righe per le due tabelle sono descritti nell'elenco puntato seguente.
- La tabella
Order
ha cinque righe:-
OrderDate
1 gennaio 2019,OrderID
1,OrderLine
1,ProductID
Prod-A,OrderQuantity
5,Sales
50 -
OrderDate
1 gennaio 2019,OrderID
1,OrderLine
2,ProductID
Prod-B,OrderQuantity
10,Sales
80 -
OrderDate
2 febbraio 2019,OrderID
2,OrderLine
1,ProductID
Prod-B,OrderQuantity
5,Sales
40 -
OrderDate
2 febbraio 2019,OrderID
2,OrderLine
2,ProductID
Prod-C,OrderQuantity
1,Sales
20 -
OrderDate
3 marzo 2019,OrderID
3,OrderLine
1,ProductID
Prod-C,OrderQuantity
5,Sales
100
-
- La tabella
Fulfillment
ha quattro righe:-
FulfillmentDate
1 gennaio 2019,FulfillmentID
50,OrderID
1,OrderLine
1,FulfillmentQuantity
2 -
FulfillmentDate
2 febbraio 2019,FulfillmentID
51,OrderID
2,OrderLine
1,FulfillmentQuantity
5 -
FulfillmentDate
2 febbraio 2019,FulfillmentID
52,OrderID
1,OrderLine
1,FulfillmentQuantity
3 -
FulfillmentDate
1 gennaio 2019,FulfillmentID
53,OrderID
1,OrderLine
2,FulfillmentQuantity
10
-
Vediamo cosa accade quando si interroga il modello. Ecco una tabella di confronto delle quantità di ordine e di evasione in base alla colonna OrderID
della tabella Order
.
L'immagine presenta un risultato accurato. Tuttavia, l'utilità del modello è limitata perché è possibile filtrare o raggruppare solo in base alla tabella Order
OrderID
colonna.
Guida sulla correlazione di fatti molti-a-molti
In genere, non è consigliabile correlare due tabelle di fatti utilizzando direttamente la cardinalità molti-a-molti. Il motivo principale è che il modello non offre flessibilità nei modi in cui gli oggetti visivi del report filtrano o raggruppano. Nell'esempio, solo gli oggetti visivi possono essere filtrati o raggruppati nella colonna OrderID
della tabella Order
. Un altro motivo riguarda la qualità dei dati. Se i dati presentano problemi di integrità, è possibile che alcune righe vengano omesse durante l'esecuzione di query a causa della natura della cardinalità molti-a-uomo e relazioni limitate.
Anziché correlare direttamente le tabelle dei fatti, è consigliabile implementare un progettazione dello schema a stella . Ciò significa che si aggiungono tabelle delle dimensioni. Queste tabelle delle dimensioni sono quindi correlate alle tabelle dei fatti tramite relazioni uno-a-molti. Questo approccio di progettazione è affidabile perché offre in modo efficiente opzioni flessibili per la creazione di report. Consente di filtrare o raggruppare utilizzando una delle colonne della tabella delle dimensioni e riepilogare le colonne di qualsiasi tabella dei fatti correlata.
Si consideri una soluzione migliore.
Si notino le modifiche di progettazione seguenti:
- Il modello include ora quattro tabelle aggiuntive:
OrderLine
,OrderDate
,Product
eFulfillmentDate
. - Le quattro tabelle aggiuntive sono tutte tabelle di dimensioni in cui le relazioni uno-a-molti le collegano alle tabelle dei fatti.
- La tabella
OrderLine
contiene la colonnaOrderLineID
, che archivia il valoreOrderID
moltiplicato per 100, più il valore della colonnaOrderLine
, ovvero un ID per ogni riga dell'ordine. - Le tabelle
Order
eFulfillment
contengono ora una colonnaOrderLineID
e non contengono più le colonneOrderID
eOrderLine
. - La tabella
Fulfillment
contiene ora colonneOrderDate
eProductID
. - La tabella
FulfillmentDate
ha una relazione solo con la tabellaFulfillment
. - Tutte le colonne ID sono nascoste.
L'adozione di una progettazione di uno schema a stella offre i seguenti vantaggi:
- Gli oggetti visivi del report possono filtrare o raggruppare da qualsiasi colonna visibile dalle tabelle delle dimensioni.
- Gli oggetti visivi del report possono riepilogare qualsiasi colonna visibile dalle tabelle di fatti.
- I filtri applicati alle tabelle
OrderLine
,OrderDate
oProduct
vengono propagati a entrambe le tabelle di fatti. - Tutte le relazioni sono uno a molti e ogni relazione è una relazione regolare . I problemi di integrità dei dati non verranno mascherati. Per altre informazioni sulla valutazione delle relazioni, vedere relazioni tra modelli di in Power BI Desktop.
Correlare dati di grana più fine
Questo scenario molti a molti è molto diverso dagli altri due già descritti in questo articolo.
Si consideri un esempio che include quattro tabelle: Date
, Sales
, Product
e Target
. Le tabelle Date
e Product
sono tabelle delle dimensioni, e ciascuna ha una relazione uno-a-molti con la tabella dei fatti Sales
. Finora, rappresenta un buon design dello schema a stella. La tabella Target
, tuttavia, non è ancora stata correlata alle altre tabelle.
La tabella Target
contiene tre colonne: Category
, TargetQuantity
e TargetYear
. Le righe della tabella rivelano una granularità dell'anno e della categoria di prodotti. In altre parole, gli obiettivi, usati per misurare le prestazioni delle vendite, vengono impostati ogni anno per ogni categoria di prodotto.
Poiché la tabella Target
archivia i dati a un livello superiore rispetto alle tabelle delle dimensioni, non è possibile creare una relazione uno-a-molti. Beh, è vero solo per una delle relazioni. Si esaminerà ora come la tabella Target
può essere correlata alle tabelle delle dimensioni.
Correlare periodi di tempo a maggiore granularità
Una relazione tra le tabelle Date
e Target
deve essere una relazione uno-a-molti. Ciò è dovuto al fatto che i valori di colonna TargetYear
sono date. In questo esempio ogni colonna TargetYear
archivia la prima data dell'anno di destinazione.
Consiglio
Quando si archiviano fatti con una granularità temporale superiore al giorno, impostare il tipo di dati della colonna su Data (o su Numero intero se si utilizzano chiavi di data). Nella colonna, memorizzare un valore che rappresenta il primo giorno del periodo. Ad esempio, un periodo di anno viene registrato come 1 gennaio dell'anno e un periodo di mese viene registrato come primo giorno del mese.
È tuttavia necessario prestare attenzione per garantire che i filtri a livello di mese o di data producano un risultato significativo. Senza una logica di calcolo speciale, le visualizzazioni del report potrebbero segnalare che le date target sono letteralmente il primo giorno di ogni anno. Tutti gli altri giorni, e tutti i mesi tranne gennaio, riepilogheranno la quantità obiettivo come BLANK.
La seguente visualizzazione a matrice mostra cosa accade quando l'utente del report esegue il drill-down da un anno ai relativi mesi. Il visuale riassume la colonna TargetQuantity
. L'opzione Mostra elementi senza dati è stata abilitata per le righe della matrice.
Per evitare questo comportamento, è consigliabile controllare il riepilogo dei dati fattuali utilizzando metriche. Un modo per controllare il riepilogo consiste nel restituire BLANK quando vengono interrogati i periodi di tempo di livello inferiore. Un altro modo, definito con alcuni DAX sofisticati, consiste nel suddividere i valori in periodi di tempo di livello inferiore.
Si consideri la definizione di misura seguente che usa la funzione ISFILTERED DAX. Restituisce solo un valore quando le colonne Date
e Month
non vengono filtrate.
Target Quantity =
IF(
NOT ISFILTERED('Date'[Date])
&& NOT ISFILTERED('Date'[Month]),
SUM(Target[TargetQuantity])
)
Nella matrice visiva seguente viene utilizzata la misura Target Quantity
. Mostra che tutte le quantità obiettivi mensili sono BLANK.
Collegare a un livello di dettaglio più fine (non data)
È necessario un approccio di progettazione diverso quando si correla una colonna non legata a una data da una tabella dimensionale a una tabella dei fatti, ed è a un livello di granularità superiore rispetto alla tabella dimensionale.
Le colonne Category
(sia dalle tabelle Product
che da Target
) contengono valori duplicati. Quindi, non c'è un lato "uno" per una relazione uno-a-molti. In questo caso, è necessario creare una relazione molti-a-molti. La relazione deve propagare i filtri in una singola direzione, dalla tabella delle dimensioni alla tabella dei fatti.
Ora diamo un'occhiata alle righe della tabella.
Nella tabella Target
sono presenti quattro righe: due righe per ogni anno di destinazione (2019 e 2020) e due categorie (Abbigliamento e Accessori). Nella tabella Product
sono presenti tre prodotti. Due appartengono alla categoria abbigliamento, e uno appartiene alla categoria accessori. Uno dei colori dell'abbigliamento è verde e i due rimanenti sono blu.
Una visualizzazione della tabella raggruppata in base alla colonna Category
della tabella Product
produce il seguente risultato. Tuttavia, questo oggetto visivo produce il risultato corretto. Consideriamo ora cosa accade quando la colonna Color
della tabella Product
viene usata per raggruppare la quantità target.
La visualizzazione produce una rappresentazione errata dei dati. Cosa succede qui?
Un filtro sulla colonna Color
della tabella Product
restituisce due righe. Una delle righe è per la categoria Clothing e l'altra per la categoria Accessori. Questi due valori di categoria vengono propagati come filtri alla tabella Target
. In altre parole, poiché il colore blu viene utilizzato dai prodotti appartenenti a due categorie, tali categorie vengono usate per filtrare gli obiettivi.
Per evitare questo comportamento, come descritto in precedenza, è consigliabile controllare il riepilogo dei dati relativi ai fatti usando delle misure.
Si consideri la definizione di misura seguente. Si noti che tutte le colonne della tabella Product
al di sotto del livello di categoria vengono testate per i filtri.
Target Quantity =
IF(
NOT ISFILTERED('Product'[ProductID])
&& NOT ISFILTERED('Product'[Product])
&& NOT ISFILTERED('Product'[Color]),
SUM(Target[TargetQuantity])
)
Nella visualizzazione tabella seguente viene utilizzata la misura Target Quantity
. Mostra che tutte le quantità di destinazione del colore sono BLANK.
La progettazione del modello finale è simile alla seguente.
Orientamento su dati più dettagliati
Quando è necessario correlare una tabella delle dimensioni a una tabella dei fatti e la tabella dei fatti memorizza le righe a un livello più dettagliato rispetto alle righe della tabella delle dimensioni, seguire queste indicazioni:
-
Per date dei dati a grana più fine
- Nella tabella dei fatti archiviare la prima data del periodo di tempo.
- Creare una relazione uno-a-molti tra la tabella delle date e la tabella dei fatti.
-
Per altre informazioni più granulari
- Creare una relazione molti-a-molti tra la tabella delle dimensioni e la tabella dei fatti.
-
Per entrambi i tipi
- Controlla il riepilogo con la logica di misura: restituisci BLANK quando vengono utilizzate colonne di dimensione di un livello inferiore per filtrare o raggruppare.
- Nascondere le colonne riassumibili della tabella dei fatti, in modo che solo le misure possano essere utilizzate per riassumere la tabella dei fatti.
Contenuto correlato
Per altre informazioni relative a questo articolo, vedere le risorse seguenti: