Definizione
Il prodotto cartesiano non è altro che l’insieme delle coppie ordinate di due insiemi. Ad esempio se ho due insiemi:
A = {a,b,c}
B = {d,e,f}
AxB = {(a,d),(b,d),(c,d),(c,e),(c,f)
Per tre, invece:
A = {a,b}
B = {c,d}
C = {e,f}
AxBxC = {(a,c,e),(a,d,e),(a,c,f),(a,d,f),(b,c,e),(b,d,e),(b,c,f),(b,d,f)}
Per i database il prodotto cartesiano dei dati è il modo naturale per unire due set differenti.
La caratteristica del prodotto cartesiano risiede nel modo di determinare la griglia: è sufficiente conoscerne gli elementi degli assi. L’immagine seguente, realizzata in Python, mostra proprio il prodotto cartesiano fra i punti di 3 assi, appunto, cartesiani.
Il prodotto cartesiano non voluto
Un esempio di prodotto cartesiano non desiderato è facilmente riscontrabile nell’esempio del negozio, riporto un mock semplificato di due tabelle:
Account: +-----------------+--------+ + NOME + ACCOID + +-----------------+--------+ + Cristiano + 1 + + Mario + 2 + ++++++++++++++++++++++++++++ Ordini: +-----------------+---------+ + ORDINI + ACCOID + +-----------------+---------+ + 100€ + 1 + + 50€ + 1 + + 70€ + 1 + + 50€ + 1 + + 30€ + 2 + + 10€ + 2 + +++++++++++++++++++++++++++++
Eseguendo una query SQL del tipo
SELECT * FROM Account, Ordini
si ottiene proprio il prodotto cartesiano fra le due, che non è probabilmente il risultato che si vuole ottenere! (Per intenderci otterremo 12 righe).
+-----------------+-------------+ + ORDINI + NOME + +-----------------+-------------+ + 100€ + Cristiano + + 50€ + Cristiano + + 70€ + Cristiano + + 50€ + Cristiano + + 30€ + Cristiano + + 10€ + Cristiano + + 100€ + Mario + + 50€ + Mario + + 70€ + Mario + + 50€ + Mario + + 30€ + Mario + + 10€ + Mario + +++++++++++++++++++++++++++++++++
Il motivo per cui la query non produce il risultato che vogliamo, è che viene valutato di default il prodotto cartesiano fra le tabelle interrogate (operazione di CROSS JOIN): l’output è proprio l’insieme di tutte le possibili combinazioni di account e ordini, e non un insieme con il nome dell’account all’intero del db. Si dice che il JOIN cerca il percorso più lungo (o globale) per unire le due tabelle.
SELECT * FROM Account NATURAL JOIN Ordini
In questo modo si otterrà invece il risultato desiderato: i parametri con lo stesso nome e valore verranno utilizzati come fonte per l’unione. La colonna ACCOID verrà riprodotta una sola volta.
+-----------------+-----------------+ + ORDINI + ACCOID + +-----------------+-----------------+ + 100€ + Cristiano + + 50€ + Cristiano + + 70€ + Cristiano + + 50€ + Cristiano + + 30€ + Mario + + 10€ + Mario + +++++++++++++++++++++++++++++++++++++
Lo scopo di questo articolo non è presentare le JOIN, motivo per cui non mi soffermerò ulteriormente su altri esempi di questo tipo o su come modificare la query nel caso in cui ci siano colonne da unire con nomi diversi.
Quando è utile
In realtà le applicazioni del prodotto cartesiano sono moltissime. L’esempio più chiaro è nella creazione di grafici e report, ovvero ogni qual volta la combinazione di due valori deve dare un unica coppia. Ad esempio:
SELECT Negozi.Negozio, Prodotti.Prodotto FROM Negozi CROSS JOIN Prodotti
In questo modo avremo per ogni negozio i prodotti disponibili in una matrice.
Per fare un altro esempio, la prossima volta che dovete creare tutte le combinazioni di data e ora, potreste fare il prodotto cartesiano fra ore e minuti invece che innestare un ciclo dentro un altro.