Domanda

Ad esempio, Google App Engine utilizza Google Datastore, non un database standard, per archiviare i dati. Qualcuno ha qualche suggerimento per l'utilizzo di Google Datastore invece dei database? Sembra che abbia allenato la mia mente a pensare al 100% nelle relazioni di oggetti che si mappano direttamente alle strutture dei tavoli, e ora è difficile vedere qualcosa di diverso. Sono in grado di comprendere alcuni dei vantaggi di Google Datastore (ad es. Prestazioni e capacità di distribuire dati), ma vengono sacrificate alcune buone funzionalità del database (ad es. Join).

Qualcuno che ha lavorato con Google Datastore o BigTable ha qualche buon consiglio per lavorare con loro?

È stato utile?

Soluzione

Ci sono due cose principali a cui abituarsi nell'archivio dati di App Engine rispetto ai database relazionali "tradizionali":

  • L'archivio dati non fa distinzione tra inserimenti e aggiornamenti. Quando si chiama put () su un'entità, quell'entità viene archiviata nell'archivio dati con la sua chiave univoca e tutto ciò che ha quella chiave viene sovrascritto. Fondamentalmente, ogni tipo di entità nell'archivio dati si comporta come un'enorme mappa o un elenco ordinato.
  • Le query, come hai accennato, sono molto più limitate. Nessun join, per cominciare.

La cosa chiave da realizzare - e il motivo dietro entrambe queste differenze - è che Bigtable si comporta sostanzialmente come un enorme dizionario ordinato. Pertanto, un'operazione put imposta semplicemente il valore per una determinata chiave, indipendentemente da qualsiasi valore precedente per quella chiave, e le operazioni di recupero sono limitate al recupero di singole chiavi o di intervalli contigui di chiavi. Le query più sofisticate sono rese possibili con gli indici, che sono sostanzialmente solo tabelle proprie, consentendo di implementare query più complesse come scansioni su intervalli contigui.

Dopo averlo assorbito, si dispone delle conoscenze di base necessarie per comprendere le capacità e i limiti dell'archivio dati. Restrizioni che possono essere sembrate arbitrarie probabilmente hanno più senso.

La cosa chiave qui è che sebbene queste siano restrizioni su ciò che è possibile fare in un database relazionale, queste stesse restrizioni sono ciò che rende pratico il ridimensionamento al tipo di grandezza che Bigtable è progettato per gestire. Semplicemente non è possibile eseguire il tipo di query che sembra buono sulla carta ma è atrocemente lento in un database SQL.

In termini di come modificare il modo in cui si rappresentano i dati, la cosa più importante è il precalcolo. Invece di eseguire join al momento della query, precalcolare i dati e archiviarli nell'archivio dati ove possibile. Se si desidera selezionare un record casuale, generare un numero casuale e memorizzarlo con ciascun record. C'è un intero libro di cucina con questo tipo di suggerimenti e trucchi qui Modifica: il ricettario non esiste più.

Altri suggerimenti

Il modo in cui ho fatto il cambio di mentalità è dimenticare del tutto il database.

Nel mondo dei database relazionali devi sempre preoccuparti della normalizzazione dei dati e della struttura della tabella. Abbandona tutto. Basta layout la tua pagina web. Disporli tutti. Adesso guardali. Ci sei già 2/3 lì.

Se si dimentica l'idea che le dimensioni del database contano e che i dati non dovrebbero essere duplicati, ci si trova 3/4 lì e non è stato nemmeno necessario scrivere alcun codice! Lascia che le tue opinioni dettino i tuoi modelli. Non devi prendere i tuoi oggetti e renderli più bidimensionali come nel mondo relazionale. Ora puoi memorizzare oggetti con forma.

Sì, questa è una spiegazione semplificata del calvario, ma mi ha aiutato a dimenticare i database e fare semplicemente un'applicazione. Finora ho realizzato 4 app App Engine usando questa filosofia e ce ne sono altre a venire.

Rido sempre quando le persone escono - non è relazionale. Ho scritto cellectr in django ed ecco uno snippet del mio modello qui sotto. Come vedrai, ho leghe che sono gestite o allenate dagli utenti. Da una lega posso ottenere tutti i manager o da un determinato utente posso restituire la lega che allena o dirige.

Solo perché non esiste un supporto specifico per le chiavi esterne non significa che non puoi avere un modello di database con relazioni.

I miei due penny.


class League(BaseModel):
    name = db.StringProperty()    
    managers = db.ListProperty(db.Key) #all the users who can view/edit this league
    coaches = db.ListProperty(db.Key) #all the users who are able to view this league

    def get_managers(self):
        # This returns the models themselves, not just the keys that are stored in teams
        return UserPrefs.get(self.managers)

    def get_coaches(self):
        # This returns the models themselves, not just the keys that are stored in teams
        return UserPrefs.get(self.coaches)      

    def __str__(self):
        return self.name

    # Need to delete all the associated games, teams and players
    def delete(self):
        for player in self.leagues_players:
            player.delete()
        for game in self.leagues_games:
            game.delete()
        for team in self.leagues_teams:
            team.delete()            
        super(League, self).delete()

class UserPrefs(db.Model):
    user = db.UserProperty()
    league_ref = db.ReferenceProperty(reference_class=League,
                            collection_name='users') #league the users are managing

    def __str__(self):
        return self.user.nickname

    # many-to-many relationship, a user can coach many leagues, a league can be
    # coached by many users
    @property
    def managing(self):
        return League.gql('WHERE managers = :1', self.key())

    @property
    def coaching(self):
        return League.gql('WHERE coaches = :1', self.key())

    # remove all references to me when I'm deleted
    def delete(self):
        for manager in self.managing:
            manager.managers.remove(self.key())
            manager.put()
        for coach in self.managing:
            coach.coaches.remove(self.key())
            coaches.put()            
        super(UserPrefs, self).delete()    

Sono venuto dal mondo dei database relazionali, poi ho trovato questa cosa di Datastore. ci sono voluti diversi giorni per appenderlo. bene ci sono alcune delle mie scoperte.

Devi già sapere che Datastore è costruito su scala e questa è la cosa che lo separa da RDMBS. per adattarsi meglio con un set di dati di grandi dimensioni, App Engine ha apportato alcune modifiche (alcune significa molte modifiche).

RDBMS VS DataStore
Struttura
Nel database, di solito strutturiamo i nostri dati in Tabelle, Righe che è in Datastore diventa Tipi ed entità .

Relazioni
In RDBMS, la maggior parte delle persone segue la relazione One-to-One, Many-to-One, Many-to-Many, In Datastore, in quanto ha " Nessun join " ma possiamo ancora raggiungere la nostra normalizzazione usando " ReferenceProperty " per esempio. Relazione individuale Esempio .

Indici
Di solito in RDMBS realizziamo indici come chiave primaria, chiave esterna, chiave univoca e chiave indice per accelerare la ricerca e migliorare le prestazioni del nostro database. Nel datastore, devi creare almeno un indice per tipo (genererà automaticamente generare che ti piaccia o no) perché il datastore cerca la tua entità sulla base di questi indici e credimi che è la parte migliore, In RDBMS puoi cercare usando un campo non indice anche se ci vorrà del tempo ma lo farà. In Datastore non è possibile effettuare ricerche utilizzando la proprietà non indice.

Conteggio
In RDMBS, è molto più facile contare (*) ma nel datastore, per favore non pensarlo nemmeno in modo normale (Sì, c'è una funzione di conteggio) in quanto ha limite 1000 e costerà tanto piccola operazione come entità che non è buona ma abbiamo sempre buone scelte, possiamo usare Shard Counters .

Vincoli unici
In RDMBS, adoriamo questa funzionalità, giusto? ma Datastore ha la sua strada. non puoi definire una proprietà come unica :(.

Query
GAE Datatore offre una funzionalità migliore molto COME (Oh no! datastore non ha una LIKE Keyword) SQL che è GQL .

Inserimento dati / Aggiorna / Elimina / Seleziona
Questo è ciò a cui siamo tutti interessati, poiché in RDMBS è necessaria una query per Inserisci, Aggiorna, Elimina e Seleziona proprio come RDBMS, Datastore ha inserito, eliminato, ottenuto (non eccitarsi troppo) perché Datastore inserisce o ottiene in termini di Scrivi, leggi, piccole operazioni (Leggi Costi per chiamate su datastore ) e è qui che entra in azione la modellazione dei dati. devi ridurre al minimo queste operazioni e mantenere la tua app in esecuzione. Per ridurre Operazione di lettura puoi utilizzare Memcache .

Dai un'occhiata alla documentazione di Objectify. Il primo commento in fondo alla pagina dice:

" Bello, anche se hai scritto questo per descrivere Objectify, è anche una delle spiegazioni più concise dello stesso datastore appengine che abbia mai letto. Grazie. & Quot;

https://github.com/objectify/objectify/wiki/Concepts

Se sei abituato a pensare a entità mappate su ORM, in pratica è così che funziona un archivio dati basato su entità come App Engine di Google. Per qualcosa come i join, puoi guardare proprietà di riferimento . Non devi preoccuparti se utilizza BigTable per il back-end o qualcos'altro poiché il back-end è estratto dalle interfacce API di GQL e Datastore.

Il modo in cui guardo il datastore è, kind identifica la tabella, di per sé, e l'entità è una riga singola all'interno della tabella. Se Google dovesse prendere una specie di un solo grande tavolo senza struttura e puoi scaricare tutto ciò che vuoi in un'entità. In altre parole, se le entità non sono legate a un tipo, praticamente si può avere qualsiasi struttura in un'entità e archiviarle in una posizione (tipo di file di grandi dimensioni senza struttura, ogni riga ha una struttura propria).

Ora torniamo al commento originale, google datastore e bigtable sono due cose diverse, quindi non confondere google datastore con il senso della memorizzazione dei dati del datastore. Bigtable è più costoso di bigquery (motivo principale per cui non ci siamo riusciti). Bigquery ha giusti join e RDBMS come il linguaggio sql ed è più economico, perché non usare bigquery. Detto questo, bigquery ha alcune limitazioni, a seconda della dimensione dei tuoi dati che potresti incontrare o meno.

Inoltre, in termini di pensiero in termini di archivio dati, penso che un'istruzione corretta sarebbe stata "pensare in termini di database NoSQL". Ce ne sono troppi disponibili oggi in questi giorni, ma quando si tratta di prodotti google tranne google cloud SQL (che è mySQL) tutto il resto è NoSQL.

Essendo radicato nel mondo dei database, un archivio di dati per me sarebbe una tabella gigante (da cui il nome "bigtable"). BigTable è un cattivo esempio però perché fa molte altre cose che un tipico database potrebbe non fare, eppure è ancora un database. È probabile che a meno che tu non sappia che devi costruire qualcosa come Google "bigtable", probabilmente starai bene con un database standard. Ne hanno bisogno perché gestiscono insieme quantità insane di dati e sistemi e nessun sistema disponibile in commercio può davvero fare il lavoro esattamente come può dimostrare di aver bisogno del lavoro da svolgere.

(riferimento bigtable: http://en.wikipedia.org/wiki/BigTable )

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