Qualcuno può spiegare questo concetto one-to-one, one-to-many, many-to-one, many-to-many rispetto agli ORM?

7

Molti siti ORM e tutorial SQL menzionano queste relazioni come se fossero ovvie o da dare per scontate, ma non capisco appieno perché le distinzioni debbano essere fatte.

Considera due tabelle A e B, entrambe con campi ID e linkaggi tra queste due tabelle.

La mia comprensione è questa:

  1. Relazione one-to-one: se hai una riga in A, hai al massimo una riga corrispondente in B e viceversa. Penso che in questo tipo di scenario potresti probabilmente combinare le tabelle, probabilmente, ma questo va oltre lo scopo.

  2. Relazione uno-a-molti: se hai una riga in A, puoi avere un numero qualsiasi di righe corrispondenti in B. Ma se hai una riga in B, al massimo c'è solo una riga corrispondente in A.

  3. Relazione molti-a-uno: già descritta in 2.

  4. Relazione molti-a-molti: se hai una riga in A, ci può essere un numero qualsiasi di righe corrispondenti in B. Se hai una riga in B, ci può essere un numero qualsiasi di righe corrispondenti in A .

Quindi, se questo è il caso, allora perché, in un ORM, dobbiamo fare la distinzione tra questi casi? Perché non è sufficiente dire: "Ecco l'oggetto A. Contiene un riferimento o una lista di riferimenti all'oggetto B." Perché devo menzionare esplicitamente "Questo riferimento all'oggetto B? Questa è una relazione uno-a-uno". O "questa è una relazione molti-a-molti", ecc.

    
posta The 29th Saltshaker 19.08.2016 - 15:19
fonte

4 risposte

2

Perché la molteplicità di connessioni è una cosa estremamente importante. E con cose importanti è meglio essere espliciti che avere cose magiche.

Che cosa succede se per esempio A ha un elenco di riferimenti a B e B ha un elenco di riferimenti a A . Questa relazione molti-a-molti o due relazioni molti-a-uno?

Solo perché A ha fatto riferimento a B e B ha fatto riferimento a A non rende la stessa connessione. E se non puoi essere sicuro, è meglio non fare nulla e lasciare tutto all'utente della biblioteca. ORM non può ottenere abbastanza informazioni dal modello oggetto stesso. Questo è il motivo per cui sono necessari metadati aggiuntivi, in forma di XML o annotazioni, per stabilire correttamente le connessioni tra le entità e la loro molteplicità.

Qualcosa del genere:

Unaltromodoperguardarloècomequesto:conlarelazionemolti-a-molti,sel'elementodiAfariferimentoall'articoloB,ilsistemagarantisceanchecheBfaràriferimentoallostessoarticoloAeviceversa.Conduerelazionimolte-a-uno,questononèilcaso.L'articolodiApuòfareriferimentoall'articolodiB,malostessooggettoBnondeve(mapuò)fareriferimentoallostessoarticoloAdinuovo.

Hounadomandaperte,comesarebberoleclassiperduecasiinquestodiagramma:

Ok, prova l'ultimo tentativo di insegnare la modellazione di base. Quali sono le relazioni in queste classi:

class A {
    List<B> RelationX;
    B RelationY;
}

class B {
    A RelationX;
    LIST<A> RelationY;
}
    
risposta data 19.08.2016 - 15:30
fonte
2

ORM è una rappresentazione orientata agli oggetti dei dati nel database. Supponiamo di avere due classi A e B come nel tuo esempio. Come immagazziniamo i riferimenti che modellano quelle relazioni a chiave esterna come le hai nel database?

class A {
  B b;
}

o

class A {
  Collection<B> b;
}

Questo è il punto cruciale del problema qui: c'è una relazione one-to-one o one-to-many? Ciò cambia la struttura dei dati che usiamo nel codice generato: un riferimento o puntatore non elaborato o una raccolta.

Per i linguaggi popolari come Java e C # che utilizzano ORM e il controllo dei tipi statici pesantemente nell'uso popolare, questo è un grosso problema. Dobbiamo sapere in anticipo non solo quale tipo di oggetto è collegato ma quanti . Il motivo è che se ce ne può essere più di uno, abbiamo bisogno di un livello di riferimento indiretto in base al quale archiviamo i riferimenti a oggetti in una raccolta. Il compilatore applica l'accesso corretto utilizzando il tipo corretto (ad esempio B o Collection<B> ).

Sembri un po 'confuso riguardo all'importanza di questo. Non è sufficiente conoscere "A links to B" ma anche la cardinalità.

Immagina un tipico sistema di ordinamento web come Amazon o uno qualsiasi dei cento sistemi in cui inserisci le tue informazioni personali e acquisti cose.

Di solito inserisci il tuo nome e indirizzo tra altri dettagli. Questa affermazione è enorme, però: quanti indirizzi hai? Normalmente, solo due: spedizione e fatturazione, e possono essere uguali.

Ora immagina un sistema in cui la cardinalità viene sventolata a mano. Forse trovo un modo per inserire due indirizzi di fatturazione. Quale sistema utilizza? A livello di codice, accede a una raccolta di indirizzi e ne seleziona uno casuale? O c'è un metodo sepolto lì chiamato Customer.getBillingAddress() che restituisce zero o uno? In cosa è più facile codificare?

No, l'applicazione della cardinalità sia a livello di database PK / FK sia nel codice utilizzando metodi staticamente corretti rende il sistema più robusto e più facile da capire quando si guarda il codice. Questo sarebbe il modello di codice corretto per gli indirizzi dei miei clienti:

class Customer {
  Address billingAddress;
  Collection<Address> shippingAddresses;
}

Ora il codice che gestisce il cliente sa che c'è solo un indirizzo di fatturazione, ma posso facilmente inserire più indirizzi di spedizione per me, famiglia, amici, ecc. Il codice sa che possono esserci più e forse iterare su di essi durante il checkout Posso selezionare dove voglio spedire i miei articoli. Ma quando si carica la mia carta di credito, utilizza l'unico indirizzo di fatturazione.

    
risposta data 19.08.2016 - 16:34
fonte
2

Dopo aver riflettuto due volte sulla tua domanda, sono tentato di dare una risposta leggermente diversa rispetto alle altre qui.

Se si prende un modello di oggetto senza alcuna cardinalità specifica per una relazione tra due classi A e B, un ORM potrebbe sempre trattarlo come una potenziale relazione molti-a-molti. Quindi tecnicamente, potrebbe generare o utilizzare le tabelle A e B sul proprio DB, generare una tabella di collegamento aggiuntiva A_B e generare tutto il codice correlato. Poiché qualsiasi relazione molti-a-molti sul DB potrebbe essere utilizzata anche per archiviare relazioni one-to-one o one-to-many, tecnicamente ciò funzionerebbe.

Tuttavia, questo approccio avrebbe due grossi svantaggi:

  1. Sarebbe estremamente dispendioso . Notare che la tabella di collegamento aggiuntiva non sarebbe necessaria se l'ORM sapesse in anticipo che una relazione è solo 1: 1 o uno-a-molti. Ad esempio, avere sempre a che fare con record superflui nella tabella dei collegamenti, così come con istruzioni SQL che sono due volte più complesse che devono essere, è un grande spreco di spazio di archiviazione e di CPU. Stesse vincite per il codice client generato: ottenere una raccolta in una classe solo per la memorizzazione di un singolo valore rende il codice che utilizza questa raccolta più complicata, ha bisogno di più memoria ed è potenzialmente più lento.

  2. Il database e il codice generato non possono garantire l'integrità dei dati per te, quindi se da un punto di vista aziendale una relazione non deve essere molti-a-molti, ma 1: n o 1: 1, devi implementarlo manualmente nel codice circostante. Ad esempio, quando c'è una raccolta utilizzata per un business case 1: 1, il tuo programma deve assicurarsi di riempirlo con un solo valore al massimo. Se, tuttavia, la classe conterrà solo un riferimento a un singolo oggetto anziché a una raccolta, non potrà essere utilizzata in modo errato, quindi non è necessario alcun codice aggiuntivo.

Quindi, in breve, tecnicamente sarebbe possibile, ma sarebbe estremamente dispendioso e ostacolare l'obiettivo degli ORM di semplificare la programmazione dei database.

    
risposta data 20.08.2016 - 12:08
fonte
-2

ORM è in realtà un'abbreviazione per Object Relational Mapping. Se ti aspetti di non aver bisogno di una mappatura "relazionale", allora non parli più di un ORM. Suppongo che potresti creare qualcosa che sia solo un Object Mapper ma che sarebbe qualcosa di completamente diverso.

    
risposta data 19.08.2016 - 18:46
fonte

Leggi altre domande sui tag