Domanda

Ultimamente ho letto molto su come i join nelle query DB rallentano le cose. Evidentemente Google App Engine non lo consente nemmeno.

Mi chiedo come le persone progettino un'app senza join però. Ad esempio, sto lavorando su un'app che ha contatti e organizzazioni . Un contatto può essere presente in molte organizzazioni e un'organizzazione può avere molti contatti. Come sarebbe possibile avere quella relazione senza una terza tabella che collega le due entità ...

contacts --< contacts_organizations >-- organizations

Significa che in GAE non puoi avere una relazione molti-a-molti? Hai appena lasciato fuori funzionalità che richiederebbero un join?

Suppongo che potresti avere una colonna TEXT organizzazioni nella tabella contatti contenente un elenco separato da spazi degli ID organizzazione per ciascun contatto. Sembra un po 'strano però.

È stato utile?

Soluzione

Di solito quando si parla di database che non consentono join, si parla di database molto grandi che non si adattano necessariamente a un server. Gli esempi recenti sono i database cloud come SimpleDB di Amazon , SQL Data Services di Microsoft e Archivio dati di Google Engine app . Alcuni offrono funzionalità di join limitate, ma la grande difficoltà sta nel fare join su " partizioni " ;. In database di grandi dimensioni come questo, si partizionano i dati in modo che non debbano risiedere sullo stesso server. Devi decidere il modo giusto di partizionarlo.

Nel tuo esempio, memorizzerei un elenco di chiavi dell'organizzazione in un campo nella tabella dei contatti e viceversa. Il design di questi database è diverso dal tipico database normalizzato. Le tabelle sono generalmente "tabelle sparse", il che significa sostanzialmente che ogni record può avere un numero qualsiasi di campi che sono sostanzialmente coppie nome / valore. Pensa a una tabella di prodotti su Amazon e a quanti campi diversi potrebbero esserci per diversi tipi di prodotti. I libri hanno un numero di pagine, ma gli MP3 hanno una durata. In una tabella sparsa, questi record verrebbero archiviati nella stessa tabella.

Altri suggerimenti

È un mito che unisce il software di rallentamento, nello stesso modo in cui sarebbe un mito affermare che i cicli di scrittura nel codice di applicazione rallentano il software.

Voglio dire, perché scrivere un ciclo? Che esegue solo le stesse righe di codice ancora e ancora! Non è stato abbastanza una volta? È uno spreco tremendo!

Le affermazioni di cui sopra devono essere ironiche.

Il mio punto è che una query contiene un join per uno scopo: ottenere la risposta giusta. L'uso dei join in modo inefficiente o inutile è ovviamente un progetto scadente, come inserire un codice invariante in un ciclo.

Evitare i join come politica generale è un esempio di ottimizzazione prematura . Se il tuo approccio alla scrittura di codice efficiente è quello di elaborare regole generali come questa, evitare di unirti non ti aiuterà.


Per quanto riguarda Google App Engine, supporta le relazioni tra entità, ma dal momento che non è strettamente un modello di database relazionale, il concetto di join non viene in realtà sviluppato. Invece, puoi ottenere entità correlate da un dato riferimento, che è più simile a un'interfaccia ORM per un modello, non è la stessa cosa di un join in SQL.

Puoi leggere di più qui: http://code.google.com/appengine/articles/modeling.html

(quel link era in un'altra risposta su questa discussione, ma è stato cancellato)

Punto di prelievo nitido: Google non proibisce i JOIN nel loro database per impedire agli utenti di eseguire "costoso". interrogazioni; il database non è relazionale, quindi il " JOIN " Il verbo SQL non è realmente applicabile in primo luogo.

In questo modo, BigTable è uguale a SimpleDB di Amazon - i dati vengono denormalizzati e eliminati schemi in modo da finire con tabelle hash enormi ed efficienti con dati arbitrari consentiti nei bucket.

Queste tabelle di hash sono molto, molto facili da ridimensionare, specialmente rispetto ai database relazionali. Per applicazioni come GAE, l'estrema scalabilità è una priorità più alta rispetto a un set completo di funzionalità.

Si utilizza db.ReferenceProperty per collegare oggetti, vedere Google App Engine: UNO-a-molti JOIN per dettagli ed esempi.

Penso che Google ti stia strappando un meccanismo pesante per il calcolo in modo da cercare modi che utilizzeranno più altri tipi di risorse, ad esempio i dischi rigidi che mantengono le tabelle di riferimento e / o contano le tabelle invece di sprecare cicli di CPU per join e calcolo aggregato.

E non è impossibile, devi solo aggirare il problema usando altri tipi di risorse per aiutarti.

È possibile eseguire join nell'applicazione anziché nel server DB, recuperando i risultati da ciascuna tabella separatamente e quindi combinandoli, ma per la maggior parte dei join in questo modo si rallenterà solo a causa della latenza di fare diversi round-trip del database anziché solo uno.

Ma: l'onesta verità è che i join non sono un tuo problema. Quando lo sono, se mai, non dovrai nemmeno fare questa domanda. Puoi contare il numero di progetti di vita reale che arrivano a questo punto sulle tue dita (principalmente Ebay) e non ci sono prove che eliminare completamente i join sia stato l'unico modo in cui questi progetti avrebbero potuto essere ridimensionati.

I database che menzioni sono, nella migliore delle ipotesi, archivi di record con versione progettati per archiviare volumi di dati molto grandi su più server. Chiamarli "database" sarebbe un allungamento. Non supportano join, né transazioni ACID, rollback, ecc. È possibile scrivere applicazioni senza di esse, ma spesso si dovrà fare più lavoro per fornire la funzionalità.

Per:

contacts --< contacts_organizations >-- organizations

Puoi deNormailize e archiviare organizzazioni in contatti e contatti in organizzazioni. Ma dovrai far valere l'integrità referenziale nell'accordo dell'applicazione con l'aggiornamento simultaneo ad entrambe le tabelle.

Una soluzione migliore sarebbe quella di archiviare i dati in tre tabelle e fare i 'join' da soli.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top