Come pensare negli archivi dati anziché nei database?


183

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. Le prestazioni e la 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?


DataSource è una vecchia API che stiamo gradualmente rimuovendo: era molto legata a un modello di connessione al database. DataStore è l'API di basso livello che consente l'accesso a un approccio "raw" basato sullo streaming al contenuto GIS, utilizzando FeatureReaders e FeatureWriter.
murali,

Ora Google Cloud SQL fornisce supporto per database relazionale per Google App Engine. Se cerchi ancora una soluzione per gli archivi dati, puoi utilizzare Google Cloud SQL .
Chandana,

Potresti voler controllare l'API Mungo Datastore: bit.ly/13eSDpr
quark

Risposte:


149

Esistono due cose principali a cui abituarsi nel datastore di App Engine rispetto ai database relazionali "tradizionali":

  • Il datastore non fa distinzione tra inserti 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. No join, per cominciare.

La cosa chiave da capire - e la ragione 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 dagli indici, che sono fondamentalmente solo tabelle proprie, consentendo di implementare query più complesse come scansioni su intervalli contigui.

Una volta assorbito ciò, hai le 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 si tratti di 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 calcolo preliminare. 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 ricette con questo tipo di suggerimenti e trucchi qui Modifica: Il libro di cucina non esiste più.


4
Buone notizie, Internet non ha dimenticato il libro di cucina, vale a dire l'archivio di Internet non ha dimenticato. Il fantasma del sito esiste ancora qui: web.archive.org/web/20090416113704/http://…
EasilyBaffled

42

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 a 3/4 e non è nemmeno necessario scrivere alcun codice! Lascia che le tue opinioni dettino le tue modelle. 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 una domanda. Finora ho realizzato 4 app App Engine usando questa filosofia e ce ne sono altre a venire.


2
Mi piace il "Lascia che le tue opinioni dettino le tue modelle". po. Penso che sia un blocco proveniente da RDBMS, ma semplifica tutto.
cbednarski,

23

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 è possibile avere un modello di database con relazioni.

I miei due pence.


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()    

12

Venivo 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 del
Nel database, di solito strutturiamo i nostri dati in Tabelle, Righe che si trovano in Datastore diventano 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, Dato che ha la cosa "No Joins", ma possiamo ancora raggiungere la nostra normalizzazione usando " ReferenceProperty "Ad esempio Esempio di relazione uno a uno .

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. In archivio dati, devi fare almeno uno indice per ogni tipo (che verrà automaticamente genererà che vi piaccia o no) perché datastore cercare il vostro soggetto sulla base di questi indici e credetemi che è la parte migliore, in RDBMS è possibile cercare utilizzando campo non indicizzato 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 un limite di 1000 e costerà un'operazione piccola quanto l'entità che non è buono ma abbiamo sempre buone scelte, possiamo usare segnalini Shard .

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

Query
GAE Datatore fornisce una funzione di una migliore molto COME (Oh no! Datastore non hai COME parola chiave) di SQL che è GQL .

Data Insert / Update / Delete / Select
Questo è ciò a cui tutti noi siamo interessati, poiché in RDMBS abbiamo bisogno di una query per Insert, Update, Delete e Select proprio come RDBMS, Datastore ha inserito, eliminato, ottenuto (non eccitatelo troppo) perché Datastore mettere o ottenere in termini di scrittura, lettura, piccole operazioni ( costi di lettura per le chiamate su archivio dati ) ed è qui che entra in azione la modellazione dei dati. devi ridurre al minimo queste operazioni e mantenere la tua app in esecuzione. Per ridurre l' operazione di lettura è possibile utilizzare Memcache .



3

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 le proprietà di riferimento . Non è necessario preoccuparsi se utilizza BigTable per il back-end o qualcos'altro poiché il back-end viene estratto dalle interfacce API di GQL e Datastore.


1
Un problema con le proprietà di riferimento è che possono creare rapidamente un problema di query 1 + N. (Tirare 1 query per trovare 100 persone, quindi eseguire un'altra query per ognuna di esse per ottenere person.address.)
0124816

Il collegamento alle "proprietà di riferimento" viene interrotto, probabilmente con l'aggiunta del supporto Java. Prova: code.google.com/appengine/docs/python/datastore/…
Spike0xff

collegamento fisso. sentiti libero di modificare qualsiasi risposta se / quando hai abbastanza rappresentante.
Mark Cidade,

0

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 una struttura in un'entità e archiviarle in una posizione (tipo di file di grandi dimensioni senza struttura, ogni riga ha una struttura propria).

Ora tornando 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 adattati). 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 riscontrare o meno.

Inoltre, in termini di pensiero in termini di archivio dati, penso che un'affermazione 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.


-6

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 di simile al "bigtable" di Google, 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 )


La domanda riguarda specificamente Google App Engine, che utilizza Bigtable; l'utilizzo di un database relazionale non è un'opzione.
Nick Johnson,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.