2014-02-09 7 views
15

Ich erstelle eine Google App Engine-Anwendung (Python) und ich lerne über das allgemeine Framework. Ich habe mir das Tutorial und die Dokumentation für den NDB-Datenspeicher angeschaut, und ich habe Schwierigkeiten, mich mit den Konzepten zu beschäftigen. Ich habe einen großen Hintergrund mit SQL-Datenbanken und ich habe noch nie mit einem anderen Datenspeichersystem gearbeitet, daher denke ich, dass ich in Schwierigkeiten gerate.Einfache Erklärung von Google App Engine NDB Datenspeicher

Mein derzeitiges Verständnis ist: Der NDB-Datenspeicher ist eine Sammlung von Entitäten (analog zu DB-Datensätzen), die Eigenschaften haben (analog zu DB-Feldern/Spalten). Entitäten werden mithilfe eines Modells (analog zu einem DB-Schema) erstellt. Jede Entität hat einen Schlüssel, der beim Speichern generiert wird. Dies ist der Punkt, an dem ich Probleme bekomme, weil diese Schlüssel anscheinend keine Analogie zu SQL-Konzepten haben. Sie scheinen Primärschlüsseln für Tabellen ähnlich zu sein, aber diese sind enger an Datensätze gebunden und tatsächlich sind sie selbst Felder. Diese NDB-Schlüssel sind keine Eigenschaften von Entitäten, sondern werden als separate Objekte von Entitäten betrachtet. Wenn eine Entität im Datenspeicher gespeichert ist, können Sie diese Entität mithilfe ihres Schlüssels abrufen.

Eine meiner großen Fragen ist, wo bekommen Sie die Schlüssel dafür? Einige der Dokumente, die ich gesehen habe, zeigten Beispiele, in denen Schlüssel einfach erstellt wurden. Ich verstehe das nicht. Es scheint, dass beim Speichern von Entitäten die Methode put() einen Schlüssel zurückgibt, der später verwendet werden kann. Wie können Sie einfach Schlüssel erstellen und Ids definieren, wenn die Originalschlüssel vom Datenspeicher generiert werden?

Eine andere Sache, mit der ich zu kämpfen habe, ist das Konzept der Abstammung mit Schlüsseln. Sie können übergeordnete Schlüssel beliebiger Art definieren. Gibt es dafür ein vordefiniertes Schema? Wenn ich beispielsweise eine Modellunterklasse namens 'Person' hatte und ich einen Schlüssel der Art 'Person' erstellt habe, kann ich diesen Schlüssel als Eltern eines anderen Typs verwenden? Wenn ich zum Beispiel einen 'Schuh'-Schlüssel als Kind eines' Personen'-Schlüssels haben möchte, könnte ich dann auch einen 'Auto'-Schlüssel erklären, um ein Kind desselben' Personen'-Schlüssels zu sein? Oder kann ich nach dem Hinzufügen der "Schuh" -Taste nicht mehr?

Ich möchte wirklich nur eine einfache Erklärung des NDB-Datenspeichers und seiner API für jemanden aus einem hauptsächlich SQL-Hintergrund.

+2

Sie haben alles vergessen, was Sie über SQL wissen, wenn Sie über den Datenspeicher nachdenken. Der Datenspeicher speichert ganze Entitäten nach Schlüssel, einschließlich Eigenschaftsnamen. Separat erstellt es Indizes, die bestimmte Kriterien erfüllen - einige automatisch und einige manuell definiert. Lese etwas - https://developers.google.com/appengine/docs/python/datastore/entities –

+2

Ich persönlich denke, dass es ein großer Fehler war, GQL einzubauen, weil Leute aus einem SQL-Hintergrund "select * from MyEntity" und sofort sehen fange an, in SQL zu denken. Welches ist wirklich ein Rezept für schlecht peforming Anwendungen. Das ist nur meine Meinung. –

Antwort

12

Ich denke, Sie haben Dinge in Ihrem Kopf übermäßig komplizieren. Wenn Sie eine Entität erstellen, können Sie ihr entweder einen selbst gewählten Namenschlüssel geben oder diese auslassen und dem Datenspeicher eine numerische ID zuweisen. So oder so, wenn Sie put aufrufen, wird der Datenspeicher den Schlüssel zurückgeben, der in der Form [<entity_kind>, <id_or_name>] gespeichert wird (eigentlich schließt das auch die Anwendungs-ID und einen beliebigen Namespace mit ein, aber ich werde das aus Gründen der Übersichtlichkeit weglassen).

Sie können Entitätsmitglieder einer Entitätsgruppe erstellen, indem Sie ihnen einen Vorfahren geben. Dieser Vorfahr muss sich nicht wirklich auf eine existierende Entität beziehen, obwohl dies normalerweise der Fall ist. Alles, was mit einem Vorfahren geschieht, ist, dass der Schlüssel der Entität den Schlüssel des Vorfahren enthält: so sieht es nun wie [<parent_entity_kind>, <parent_id_or_name>, <entity_kind>, <id_or_name>] aus. Sie können die Entity jetzt nur durch Einschließen des übergeordneten Schlüssels abrufen. In diesem Beispiel könnte die Shoe-Entität ein Kind der Person sein, unabhängig davon, ob diese Person zuvor erstellt wurde: Es ist das Kind, das den Vorfahren kennt und nicht umgekehrt.

(Beachten Sie, dass die Vorfahren Pfad beliebig erweitert werden kann: Das Kind Entität kann selbst ein Vorfahr sein, usw. In diesem Fall wird die Gruppe von der Einheit an der Spitze des Baumes bestimmt wird.).

Das Speichern von Entitäten als Teil einer Gruppe hat Vorteile in Bezug auf die Konsistenz, da eine Abfrage innerhalb einer Entitätsgruppe immer garantiert vollständig konsistent ist, während außerhalb der Abfrage letztlich nur Übereinstimmung besteht. Es gibt jedoch auch Nachteile dahingehend, dass die Schreibrate einer Entitätsgruppe für die gesamte Gruppe auf 1 pro Sekunde begrenzt ist.

+0

Ok, ich denke ich bekomme es jetzt. Wie kann ich einer Entität einen Schlüssel zuweisen, bevor dieser gespeichert wird? Wenn das keinen Sinn ergibt, frage ich mich, dass ich mich frage, wie ich meine eigene ID dem Schlüssel einer Entität zuweisen kann, wenn ich diesen Schlüssel erst abrufen kann, wenn ich die Entität gespeichert habe. – jchitel

+0

Ich schaute nur auf die API und es sieht so aus, als würde ich das tun, indem ich 'entity = Entity (properties = ..., id =' ') ''. Dann gibt der Schlüssel, der durch Aufrufen von 'put()' zurückgegeben wird, einen Schlüssel mit dieser ID zurück. Ist das korrekt? – jchitel

+1

Ja, das stimmt. Oder Sie können ein vollständiges 'ndb.Key'-Objekt als 'key' -Parameter übergeben. –

7

Datenspeicher keys sind ein wenig mehr analog zu internen SQL-Zeilenbezeichner, aber natürlich nicht ganz. Bezeichner in Appengine sind ein bisschen wie SQL-Primärschlüssel. Um die gleichzeitige gleichzeitige Erstellung neuer Schlüssel durch viele Anwendungsinstanzen in einer Server-Cloud zu unterstützen, generiert AppEngine intern die Schlüssel, um die Eindeutigkeit zu gewährleisten. Ihre Anwendung definiert Parameter (Anwendungs-ID, optionaler Namespace, Typ und optionale Entitäts-ID), die AppEngine verwendet, um den Schlüsselgenerator zu erstellen. Wenn Sie keine ID angeben, wird AppEngine generate a unique numeric identifier diese you can read.

Eventuelle Konsistenz braucht Zeit, daher ist es gelegentlich effizienter, request multiple new keys in bulk. AppEngine generiert dann eine Reihe von numerischen Entitätskennungen für Sie. Sie können read their values from keys als KeyProperty metadata.

Ancestry wird verwendet, um group together writes von verwandten Einheiten aller Art für den Zweck von transactions und isolation. Es gibt kein vordefiniertes Schema dafür, aber Sie sind auf ein Elternteil pro Kind beschränkt.

In Ihrem Beispiel könnte ein bestimmter Schuh eine bestimmte Person als Eltern haben. Ein anderer spezieller Schuh könnte ein Pferd als Elternteil haben. Und ein anderer Schuh könnte keinen Elternteil haben. Viele Entitäten aller Art können denselben Elternteil haben, so dass auch mehrere Car-Entitäten diese initiale Person als Eltern haben könnten. Da der Datenspeicher schemalos ist, liegt es an Ihrer Anwendung, einem Auto zu erlauben oder zu verbieten, ein Pferd als Elternteil zu haben.

Beachten Sie, dass ein Kind seine Eltern kennt, aber ein Elternteil seine Kinder nicht kennt, da die Implementierung die Skalierbarkeit beeinträchtigen würde.