Wie kann man in Datenspeichern statt in Datenbanken denken?

183

Beispielsweise verwendet Google App Engine Google Datastore, keine Standarddatenbank, zum Speichern von Daten. Hat jemand Tipps zur Verwendung von Google Datastore anstelle von Datenbanken? Es scheint, als hätte ich meinen Verstand darauf trainiert, zu 100% in Objektbeziehungen zu denken, die direkt auf Tabellenstrukturen abgebildet werden, und jetzt ist es schwierig, etwas anders zu sehen. Ich kann einige der Vorteile von Google Datastore verstehen (z. B. Leistung und die Fähigkeit, Daten zu verteilen), aber einige gute Datenbankfunktionen werden geopfert (z. B. Joins).

Hat jemand, der mit Google Datastore oder BigTable gearbeitet hat, gute Ratschläge für die Arbeit mit ihnen?

Jim
quelle
DataSource ist eine alte API, die wir nach und nach entfernen - sie war stark an ein Datenbankverbindungsmodell gebunden. DataStore ist die Low-Level-API, die mithilfe von FeatureReaders und FeatureWriter den Zugriff auf einen "rohen" Streaming-basierten Ansatz für GIS-Inhalte ermöglicht.
Murali
Jetzt bietet Google Cloud SQL relationale Datenbankunterstützung für Google App Engine. Wenn Sie immer noch nach einer Lösung für Datenspeicher suchen, können Sie Google Cloud SQL verwenden .
Chandana
Vielleicht möchten Sie die Mungo Datastore API überprüfen: bit.ly/13eSDpr
Quarks

Antworten:

149

Im Vergleich zu "herkömmlichen" relationalen Datenbanken sind zwei wichtige Dinge an den App Engine-Datenspeicher zu gewöhnen:

  • Der Datenspeicher unterscheidet nicht zwischen Einfügungen und Aktualisierungen. Wenn Sie put () für eine Entität aufrufen, wird diese Entität mit ihrem eindeutigen Schlüssel im Datenspeicher gespeichert, und alles, was diesen Schlüssel enthält, wird überschrieben. Grundsätzlich verhält sich jede Entitätsart im Datenspeicher wie eine riesige Karte oder sortierte Liste.
  • Das Abfragen ist, wie Sie angedeutet haben, viel eingeschränkter. Zunächst einmal keine Joins.

Der Schlüssel zu erkennen - und der Grund für diese beiden Unterschiede - ist, dass Bigtable sich im Grunde wie ein riesiges geordnetes Wörterbuch verhält. Daher setzt eine Put-Operation nur den Wert für einen bestimmten Schlüssel - unabhängig von einem vorherigen Wert für diesen Schlüssel, und Abrufoperationen beschränken sich auf das Abrufen einzelner Schlüssel oder zusammenhängender Schlüsselbereiche. Anspruchsvollere Abfragen werden mit Indizes ermöglicht, bei denen es sich im Grunde nur um eigene Tabellen handelt. So können Sie komplexere Abfragen als Scans für zusammenhängende Bereiche implementieren.

Sobald Sie dies aufgenommen haben, verfügen Sie über die grundlegenden Kenntnisse, um die Funktionen und Einschränkungen des Datenspeichers zu verstehen. Einschränkungen, die willkürlich erschienen sind, sind wahrscheinlich sinnvoller.

Das Wichtigste dabei ist, dass dies zwar Einschränkungen hinsichtlich der Möglichkeiten in einer relationalen Datenbank sind, diese Einschränkungen es jedoch praktisch machen, auf die Größe zu skalieren, für die Bigtable ausgelegt ist. Sie können einfach keine Abfrage ausführen, die auf dem Papier gut aussieht, in einer SQL-Datenbank jedoch äußerst langsam ist.

Das Wichtigste bei der Änderung der Darstellung von Daten ist die Vorberechnung. Anstatt Joins zur Abfragezeit durchzuführen, berechnen Sie die Daten vorab und speichern Sie sie nach Möglichkeit im Datenspeicher. Wenn Sie einen zufälligen Datensatz auswählen möchten, generieren Sie eine Zufallszahl und speichern Sie diese mit jedem Datensatz. Es gibt ein ganzes Kochbuch dieser Art von Tipps und Tricks hier Edit: Das Kochbuch ist nicht mehr vorhanden.

Nick Johnson
quelle
4
Gute Nachrichten, das Internet hat das Kochbuch nicht vergessen, nämlich das Internetarchiv hat es nicht vergessen. Der Geist der Site existiert hier noch: web.archive.org/web/20090416113704/http://…
EasilyBaffled
42

Die Art und Weise, wie ich den Gedankenwechsel durchgeführt habe, besteht darin, die Datenbank insgesamt zu vergessen.

In der relationalen Datenbankwelt müssen Sie sich immer um die Datennormalisierung und Ihre Tabellenstruktur kümmern. Schluss mit allem. Layouten Sie einfach Ihre Webseite. Lege sie alle aus. Jetzt sieh sie dir an. Du bist schon 2/3 da.

Wenn Sie die Vorstellung vergessen, dass die Datenbankgröße wichtig ist und Daten nicht dupliziert werden sollten, sind Sie zu 3/4 da und mussten nicht einmal Code schreiben! Lassen Sie Ihre Ansichten Ihre Modelle bestimmen. Sie müssen Ihre Objekte nicht mehr wie in der relationalen Welt zweidimensional machen. Sie können jetzt Objekte mit Form speichern.

Ja, dies ist eine vereinfachte Erklärung der Tortur, aber es hat mir geholfen, Datenbanken zu vergessen und einfach einen Antrag zu stellen. Ich habe bisher 4 App Engine-Apps mit dieser Philosophie erstellt und es werden noch weitere folgen.

user19087
quelle
2
Ich mag das "Lassen Sie Ihre Ansichten Ihre Modelle diktieren." bisschen. Ich denke, das ist ein Problem von RDBMS, aber es vereinfacht alles.
Cbednarski
23

Ich kichere immer, wenn Leute herauskommen - es ist nicht relational. Ich habe cellectr in django geschrieben und hier ist ein Ausschnitt meines Modells unten. Wie Sie sehen werden, habe ich Ligen, die von Benutzern verwaltet oder trainiert werden. Ich kann von einer Liga alle Manager bekommen, oder von einem bestimmten Benutzer kann ich die Liga zurückgeben, die sie trainiert oder verwaltet.

Nur weil es keine spezifische Fremdschlüsselunterstützung gibt, heißt das nicht, dass Sie kein Datenbankmodell mit Beziehungen haben können.

Meine zwei 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()    
Phil Stollery
quelle
12

Ich kam aus der Welt der relationalen Datenbanken, dann fand ich dieses Datenspeicher-Ding. Es dauerte mehrere Tage, bis ich es verstanden hatte. Nun, es gibt einige meiner Erkenntnisse.

Sie müssen bereits gewusst haben, dass der Datenspeicher maßstabsgetreu erstellt wurde, und das ist das, was ihn von RDMBS unterscheidet. Um mit großen Datenmengen besser skalieren zu können, hat App Engine einige Änderungen vorgenommen (einige bedeuten viele Änderungen).

RDBMS VS DataStore-
Struktur
In der Datenbank strukturieren wir unsere Daten normalerweise in Tabellen, Zeilen, die sich im Datenspeicher in Arten und Entitäten befinden .

Beziehungen
In RDBMS, Die meisten Menschen folllows die One-to-One, Many-to-One, Many-to-Many - Beziehung, in Datastor, da es "Nein Joins" , was aber immer noch können wir unsere Normalisierung erreichen mit " Reference "zB Eins-zu-Eins-Beziehungsbeispiel .

Indizes
Normalerweise erstellen wir in RDMBS Indizes wie Primärschlüssel, Fremdschlüssel, eindeutiger Schlüssel und Indexschlüssel, um die Suche zu beschleunigen und die Datenbankleistung zu steigern. Im Datenspeicher müssen Sie mindestens einen Index pro Art erstellen (dieser wird automatisch generiert ob Sie ihn mögen oder nicht), da der Datenspeicher Ihre Entität anhand dieser Indizes durchsucht und mir glaubt, dass dies der beste Teil ist. In RDBMS können Sie mit suchen Nicht-Index-Feld, obwohl es einige Zeit dauern wird, aber es wird. Im Datenspeicher können Sie nicht mit Nicht-Index-Eigenschaften suchen.

Count
In RDMBS, es ist viel einfacher zu zählen (*) , sondern in Datenspeichern, Bitte nicht einmal denken , es in gewohnter Weise (Yeah gibt es eine Zählfunktion) , da sie hat 1000 - Grenze , und es wird so viel kostet kleine Opertion als die Einheit , die ist nicht gut, aber wir haben immer eine gute Auswahl, wir können Shard Counters verwenden .

Einzigartige Einschränkungen
In RDMBS lieben wir diese Funktion, oder? Aber der Datenspeicher hat seinen eigenen Weg. Sie können eine Eigenschaft nicht als eindeutig definieren :(.

Abfrage
GAE Datatore bietet eine bessere Funktion viel LIKE (Oh nein! Datenspeicher hat kein LIKE-Schlüsselwort) SQL, das GQL ist .

Daten einfügen / aktualisieren / löschen / auswählen
Dies ist der Punkt, an dem wir alle interessiert sind, da wir in RDMBS eine Abfrage für Einfügen, Aktualisieren, Löschen und Auswählen benötigen, genau wie RDBMS setzen oder in Bezug auf die erhalten schreiben, lesen, Kleine Operationen (lesen Kosten für Datenspeicher - Calls ) und das ist , wo die Datenmodellierung in Aktion. Sie müssen diese Vorgänge minimieren und Ihre App am Laufen halten. Zum Reduzieren des Lesevorgangs können Sie Memcache verwenden .

Sanjay Kushwah
quelle
6

Schauen Sie sich die Objectify-Dokumentation an. Der erste Kommentar am Ende der Seite lautet:

"Schön, obwohl Sie dies geschrieben haben, um Objectify zu beschreiben, ist es auch eine der prägnantesten Erklärungen für den Appengine-Datenspeicher selbst, den ich je gelesen habe. Danke."

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

Jon Stevens
quelle
3

Wenn Sie es gewohnt sind, über ORM-zugeordnete Entitäten nachzudenken, funktioniert ein entitätsbasierter Datenspeicher wie die App Engine von Google im Grunde genommen so. Für so etwas wie Joins können Sie sich die Referenzeigenschaften ansehen . Sie müssen sich nicht wirklich darum kümmern, ob BigTable für das Backend oder etwas anderes verwendet wird, da das Backend von den GQL- und Datastore-API-Schnittstellen abstrahiert wird.

Mark Cidade
quelle
1
Ein Problem mit Referenzeigenschaften besteht darin, dass sie schnell ein 1 + N-Abfrageproblem erstellen können. (Ziehen Sie 1 Abfrage, um 100 Personen zu finden, und stellen Sie dann für jede eine weitere Abfrage, um person.address zu erhalten.)
0124816
Der Link zu 'Referenzeigenschaften' ist unterbrochen, wahrscheinlich durch zusätzliche Java-Unterstützung. Versuchen Sie: code.google.com/appengine/docs/python/datastore/…
Spike0xff
Link behoben. Fühlen Sie sich frei, jede Antwort zu bearbeiten, wenn Sie genug Wiederholungen haben.
Mark Cidade
0

Die Art und Weise, wie ich den Datenspeicher betrachte, ist, dass die Art die Tabelle an sich identifiziert und die Entität eine einzelne Zeile innerhalb der Tabelle ist. Wenn Google Art herausnehmen würde, dann wäre es nur eine große Tabelle ohne Struktur und Sie könnten alles, was Sie wollen, in eine Entität werfen. Mit anderen Worten, wenn Entitäten nicht an eine Art gebunden sind, können Sie so ziemlich jede Struktur für eine Entität haben und an einem Ort speichern (eine Art große Datei ohne Struktur, jede Zeile hat eine eigene Struktur).

Zurück zum ursprünglichen Kommentar: Google Datastore und Bigtable sind zwei verschiedene Dinge. Verwechseln Sie also Google Datastore nicht mit dem Sinn der Datenspeicherung. Bigtable ist teurer als Bigquery (Hauptgrund, warum wir uns nicht dafür entschieden haben). Bigquery hat richtige Joins und RDBMS wie SQL-Sprache und es ist billiger, warum nicht Bigquery verwenden. Abgesehen davon hat bigquery einige Einschränkungen, abhängig von der Größe Ihrer Daten, auf die Sie möglicherweise stoßen oder nicht.

Auch in Bezug auf das Denken in Bezug auf Datenspeicher denke ich, dass die richtige Aussage "Denken in Bezug auf NoSQL-Datenbanken" gewesen wäre. Es gibt heutzutage zu viele davon, aber wenn es um Google-Produkte geht, außer Google Cloud SQL (mySQL), ist alles andere NoSQL.

ringadingding
quelle
-6

Ein Datenspeicher, der in der Datenbankwelt verwurzelt ist, wäre für mich eine riesige Tabelle (daher der Name "bigtable"). BigTable ist jedoch ein schlechtes Beispiel, da es viele andere Dinge tut, die eine typische Datenbank möglicherweise nicht tut, und dennoch eine Datenbank ist. Wenn Sie nicht wissen, dass Sie so etwas wie Googles "Bigtable" erstellen müssen, wird Ihnen wahrscheinlich eine Standarddatenbank recht sein. Sie brauchen das, weil sie wahnsinnig viele Daten und Systeme zusammen verarbeiten und kein kommerziell erhältliches System die Arbeit genau so erledigen kann, wie sie nachweisen können, dass sie die Arbeit erledigen müssen.

(Bigtable-Referenz: http://en.wikipedia.org/wiki/BigTable )

devinmoore
quelle
Die Frage bezieht sich speziell auf Google App Engine, das Bigtable verwendet. Die Verwendung einer relationalen Datenbank ist keine Option.
Nick Johnson