16

Ci scusiamo se questa domanda è troppo semplice; Sto solo entrando in nona classe.Relazioni più efficaci uno-a-molti in Google App Engine Datastore?

Sto cercando di conoscere la progettazione del database NoSQL. Voglio progettare un modello di Google Datastore che riduca al minimo il numero di operazioni di lettura/scrittura.

Ecco un esempio di giocattolo per un post di blog e commenti in una relazione uno-a-molti. Che è più efficiente: memorizzando tutti i commenti in StructuredProperty o utilizzando KeyProperty nel modello Comment?

Anche in questo caso, l'obiettivo è ridurre al minimo il numero di operazioni di lettura/scrittura sul datastore. È possibile formulare le seguenti ipotesi:

  • I commenti non verranno recuperati indipendentemente dal rispettivo post sul blog. (Ho il sospetto che questo rende lo StructuredProperty più preferibile.)
  • commenti dovranno essere ordinabili per data, voto, autore, ecc (sottoproprietà nel datastore non possono essere indicizzati, quindi forse questo potrebbe influire sulle prestazioni?)
  • Sia i post del blog che i commenti possono essere modificati (o anche cancellati) dopo la loro creazione.

Uso StructuredProperty:

from google.appengine.ext import ndb 

class Comment(ndb.Model): 
    various properties... 

class BlogPost(ndb.Model): 
    comments = ndb.StructuredProperty(Comment, repeated=True) 
    various other properties... 

Uso KeyProperty:

from google.appengine.ext import ndb 

class BlogPost(ndb.Model): 
    various properties... 

class Comment(ndb.Model): 
    blogPost = ndb.KeyProperty(kind=BlogPost) 
    various other properties... 

Sentitevi liberi di portare eventuali altre considerazioni relative a rappresentare efficacemente una relazione uno-a-molti per quanto riguarda la minimizzazione il numero di lettura/scrittura sul datastore.

Grazie.

+0

Considerare come risolvere il problema della dimensione totale dei commenti e del blogpost superiore a 1 MB. Può mai succedere? Se potesse e non avessi una buona soluzione per affrontarlo, sembrerebbe dal punto di vista della pura funzionalità che non ti preoccuperai nemmeno di una singola entità che contiene entrambi. –

+0

Un'alternativa potrebbe essere quella di archiviare tutte le chiavi dei commenti nel post del blog. Quindi è possibile recuperare tutti i commenti con un singolo ndb.get_multi (chiavi), ma consentirebbe un numero significativamente maggiore di commenti e, se si supera ancora 1 MB, sarà possibile trasferire i commenti singolarmente. –

risposta

13

Potrei sbagliarmi, ma da quello che ho capito, StructuredProperty è solo una proprietà all'interno di un'entità, ma con sotto-proprietà.

Questo significa leggere un BlogPost e tutti i suoi commenti costano solo una lettura. Quindi quando esegui il rendering della tua pagina, ti serve solo un op di lettura per l'intera pagina.

Le scritture sarebbero anche più economiche. Avrai bisogno di un op di lettura per ottenere il BlogPost, e finché non aggiorni nessuna proprietà indicizzata, sarà solo una operazione di scrittura.

È possibile gestire l'ordinamento dei commenti da soli dopo aver letto l'entità dal datastore.

È necessario sincronizzare gli aggiornamenti/modifiche dei commenti con le transazioni, per assicurarsi che un commento non sovrascriva un altro, poiché entrambi modificano la stessa entità. Potresti incorrere in problemi irrisolvibili se tutti stanno commentando e modificando lo stesso post del blog contemporaneamente.

Nell'ottimizzare per il costo, tuttavia, si colpisce un muro con la dimensione massima dell'entità di 1 MB. Ciò limiterà il numero di commenti che è possibile memorizzare per post del blog.

L'utilizzo di KeyProperty sarebbe un po 'più costoso.

Avrai bisogno di una lettura per ottenere il post del blog, più 1 query più 1 op lettura piccola per ogni commento.

Ogni commento è una nuova entità, quindi saranno almeno 4 operazioni di scrittura. Potresti voler indicizzare per ordinare, in modo che finiscano per costare ancora più operazioni di scrittura.

Per quanto riguarda i lati positivi, i commenti per post di blog sono illimitati, non è necessario preoccuparsi di sincronizzare i nuovi commenti. Potrebbe essere necessario preoccuparsi della sincronizzazione per la modifica dei commenti, ma se si limita la modifica al creatore, questo non dovrebbe essere un problema. Neanche tu devi fare l'ordinamento.

È un compromesso tra costi e caratteristiche.

3

Che dire:

from google.appengine.ext import ndb 

class Comment(ndb.Model): 
    various properties... 

class BlogPost(ndb.Model): 
    comments = ndb.KeyProperty(Comment, repeated=True) 
    various other properties... 

In questo modo, è possibile memorizzare fino a 5000 commenti per post del blog (il numero massimo di proprietà ripetute) indipendente dalle dimensioni di ogni post del blog. Non avrai bisogno di una query per recuperare i blog per un commento, puoi semplicemente fare ndb.get_multi(blog_post.comments). E per questa operazione, puoi provare a fare affidamento sul memcache di ndb. Naturalmente, dipende dal tuo caso d'uso se questa è una buona ipotesi o no.

1

essere a conoscenza di questo avvertimento quando si utilizza uno StructuredProperty ripetuto:

Non utilizzare le proprietà ripetute se si dispone di più di 100-1000 valori. (Probabilmente 1000 lo sta già spingendo). Non erano progettati per tale uso.

Vedere la risposta di Guido in GAE ndb design, performance and use of repeated properties.

Così mentre non si può colpire il limite di entità di 1 MB con StructuredProperty, si può facilmente colpire il max 100-1000 suggerito.

+0

Quindi qual è l'alternativa? Solo KeyProperty, come nella domanda? O c'è un modo migliore? – Ajedi32

+0

Un KeyProperty potrebbe funzionare se inferiore al limite del valore 100-1000, ma se si dispone di più di questo, prenderei in considerazione la possibilità di ripensare il modello dati e le funzionalità necessarie. Nel caso dell'esempio del blog, anche la memorizzazione dei commenti come singola JSONProperty potrebbe funzionare. In questo modo stai solo aggiornando/leggendo 1 entità (il BlogPost) e aggiornando la sua proprietà JSON per i commenti. Questo è simile alla soluzione StructuredProperty senza la limitazione dei valori 100-1000. Naturalmente se l'entità diventa più grande di 1 MB, questo non funzionerà (a meno che non lo divida in più entità ...), ma questo potrebbe funzionare per il tuo caso d'uso. –

Problemi correlati