Versione breve
Devo aggiungere un numero fisso di proprietà aggiuntive a ciascuna coppia in un join molti-a-molti esistente. Saltando ai diagrammi seguenti, quale delle opzioni 1-4 è il modo migliore, in termini di vantaggi e svantaggi, per raggiungere questo obiettivo estendendo il caso di base? Oppure, c'è un'alternativa migliore che non ho considerato qui?
Versione più lunga
Al momento ho due tabelle in una relazione molti-a-molti, tramite una tabella di join intermedia. Ora devo aggiungere ulteriori collegamenti alle proprietà che appartengono alla coppia di oggetti esistenti. Ho un numero fisso di queste proprietà per ogni coppia, anche se una voce nella tabella delle proprietà può essere applicata a più coppie (o addirittura essere utilizzata più volte per una coppia). Sto cercando di determinare il modo migliore per farlo e ho problemi a capire come pensare alla situazione. Semanticamente sembra che possa descriverlo ugualmente bene in uno dei seguenti modi:
- Una coppia collegata a un set di un numero fisso di proprietà aggiuntive
- Una coppia collegata a molte proprietà aggiuntive
- Molti (due) oggetti collegati a un insieme di proprietà
- Molti oggetti collegati a molte proprietà
Esempio
Ho due tipi di oggetti, X e Y, ognuno con ID univoci, e una tabella di collegamento objx_objy
con colonne x_id
e y_id
, che insieme formano la chiave primaria per il collegamento. Ogni X può essere correlata a molte Y e viceversa. Questa è l'impostazione per la mia relazione molti-a-molti esistente.
Caso base
Ora ho anche una serie di proprietà definite in un'altra tabella e una serie di condizioni in cui una data coppia (X, Y) dovrebbe avere la proprietà P. Il numero di condizioni è fisso e lo stesso per tutte le coppie. Sostanzialmente dicono "Nella situazione C1, la coppia (X1, Y1) ha la proprietà P1", "Nella situazione C2, la coppia (X1, Y1) ha la proprietà P2" e così via, per tre situazioni / condizioni per ogni coppia nel join tavolo.
opzione 1
Nella mia situazione attuale non ci sono esattamente tre queste condizioni, e non ho alcun motivo di aspettarsi che per aumentare, quindi una possibilità è quella di aggiungere colonne c1_p_id
, c2_p_id
e c3_p_id
per featx_featy
, specificando per una data x_id
e y_id
, quale proprietà p_id
ad uso in ciascuno dei tre casi .
Questa non mi sembra un'ottima idea, perché complica l'SQL a selezionare tutte le proprietà applicate a una funzionalità e non si adatta facilmente a più condizioni. Tuttavia, applica il requisito di un certo numero di condizioni per coppia (X, Y). In effetti, è l'unica opzione qui che lo fa.
opzione 2
Creare una tabella delle condizioni cond
e aggiungere l'ID condizione alla chiave primaria della tabella dei join.
Un aspetto negativo di questo è che non specifica il numero di condizioni per ciascuna coppia. Un altro è che quando sto solo considerando la relazione iniziale, con qualcosa come
SELECT objx.*, objy.* FROM objx
INNER JOIN objx_objy ON objx_objy.x_id = objx.id
INNER JOIN objy ON objy.id = objx_objy.y_id
Devo quindi aggiungere una DISTINCT
clausola per evitare voci duplicate. Questo sembra aver perso il fatto che ogni coppia dovrebbe esistere una sola volta.
Opzione 3
Creare un nuovo "ID coppia" nella tabella dei join, quindi disporre di una seconda tabella dei collegamenti tra la prima e le proprietà e le condizioni.
Questo sembra avere il minor numero di svantaggi, oltre alla mancanza di far rispettare un numero fisso di condizioni per ciascuna coppia. Ha senso però creare un nuovo ID che non identifichi altro che ID esistenti?
Opzione 4 (3b)
Sostanzialmente uguale all'opzione 3, ma senza la creazione del campo ID aggiuntivo. Ciò si ottiene inserendo entrambi gli ID originali nella nuova tabella di join, quindi contiene x_id
e y_id
campi, anziché xy_id
.
Un ulteriore vantaggio di questo modulo è che non altera le tabelle esistenti (anche se non sono ancora in produzione). Tuttavia, fondamentalmente duplica un'intera tabella più volte (o comunque si sente così) quindi non sembra l'ideale.
Sommario
La mia sensazione è che le opzioni 3 e 4 siano abbastanza simili da poterle scegliere con entrambe. Probabilmente avrei ormai se non fosse per il requisito di un piccolo numero fisso di collegamenti a proprietà, il che fa sembrare l'opzione 1 più ragionevole di quanto non sarebbe altrimenti. Sulla base di alcuni test molto limitati, l'aggiunta di una DISTINCT
clausola alle mie query non sembra influire sulle prestazioni in questa situazione, ma non sono sicuro che l'opzione 2 rappresenti la situazione così come le altre, a causa della duplicazione intrinseca causata dal posizionamento le stesse coppie (X, Y) in più righe della tabella dei collegamenti.
Una di queste opzioni è il mio modo migliore di procedere o esiste un'altra struttura che dovrei prendere in considerazione?
DISTINCT
clausola, stavo pensando a una query come quella alla fine del n. 2, che collega x
e y
attraversa xyc
ma non fa riferimento a c
... Quindi se ho (x_id, y_id, c_id)
vincolato UNIQUE
con le righe (1,1,1)
e (1,1,2)
, quindi SELECT x.id, y.id FROM x JOIN xyc JOIN y
, ne restituirò due identici righe (1,1)
, e (1,1)
.