2012-08-25 7 views
11

Gegenwärtig verwendet viel von meinem Code extensive Verwendung von Vorfahren zum Ablegen und Abrufen von Objekten. Ich möchte jedoch etwas ändern.Verwenden von Vorfahren oder Referenzeigenschaften in Google App Engine?

Ich dachte ursprünglich, dass Vorfahren dazu beigetragen haben, die Abfrage schneller zu machen, wenn Sie wüssten, wer der Vorfahre der Entität ist, nach der Sie suchen. Aber ich denke, es stellt sich heraus, dass Vorfahren hauptsächlich für die Transaktionsunterstützung nützlich sind. Ich verwende keine Transaktionen, also frage ich mich, ob Vorfahren hier eher eine Belastung für das System darstellen als eine Hilfe.

Was ich habe, ist eine Benutzer-Entität und viele andere Entitäten wie sagen, Kommentare, Tags, Freunde. Ein Benutzer kann viele Kommentare, Tags und Freunde erstellen. Wenn ein Benutzer dies tut, wird der Vorgänger für alle neu erstellten Objekte als Benutzer festgelegt. So

, wenn ich einen Kommentar erstellen, stelle ich die Vorfahren als Benutzer:

comment = Comment(aUser, key_name = commentId) 

Jetzt ist der einzige Grund, warum ich tue dies streng Zwecke zur Abfrage ist. Ich dachte, es wäre schneller, wenn ich alle Kommentare von einem bestimmten Benutzer erhalten möchte, um alle Kommentare mit einem gemeinsamen Vorfahren zu erhalten, anstatt nach allen Kommentaren zu fragen, bei denen authorEmail = userEmail ist.

Also, wenn ich alle Kommentare von einem bestimmten Benutzer erhalten mag, ich mache:

commentQuery = db.GqlQuery('SELECT * FROM Comment WHERE ANCESTOR IS :1', userKey) 

Also meine Frage ist, diese Verwendung von Vorfahren eine gut ist? Sollte jeder Kommentar stattdessen über eine ReferenceProperty verfügen, die auf das Benutzerobjekt verweist, das den Kommentar erstellt hat, und danach filtern?

(auch war, mein Denken, dass Vorfahren anstelle eines indizierten Reference mit auf Schreib Kosten sparen würde. Täusche ich mich da?)

Antwort

8

Sie haben Recht, über das Schreiben Kosten, ist ein Vorfahre Teil des Schlüssels die kommt "frei". Wenn Sie eine Referenzeigenschaft verwenden, erhöhen sich Ihre Schreibkosten, wenn die Referenzeigenschaft indiziert ist.
Da Sie die Referenzeigenschaft abfragen, müssen Sie indizieren.

Der Vorgänger ist nicht nur wichtig für Transaktionen, sondern im HRD (der Standard-Datenspeicherimplementierung). Wenn Sie nicht jeden Kommentar mit demselben Vorfahren erstellen, sind die Abfragen nicht stark konsistent.

- Nick's Kommentar hinzufügen ---
Jede Entität mit demselben Parent befindet sich in derselben Entitätsgruppe, und Schreibvorgänge in Entitätsgruppen sind serialisiert, so dass die Verwendung von Vorfahren hier die Geschwindigkeit verlangsamt, wenn Sie mehrere schreiben Entitäten gleichzeitig. Da alle Entitäten in einer Gruppe dem Benutzer gehören, der in Ihrer Instanz den Stamm der Gruppe bildet, sollte dies kein Problem sein - und tatsächlich ist das, was Sie tun, tatsächlich ein empfohlenes Designmuster .

+0

Aber verlangsamen Vorfahren mich überhaupt? Da sie beim Schreiben zusätzliche Sicherheit bieten, bin ich mir sicher, dass das etwas kostet, oder? Ich weiß nur nicht, welche Option zu gehen. – Snowman

+0

Ich weiß wirklich nicht, aber ich glaube, dass es nicht wirklich die Geschwindigkeit der Abfrage beeinflussen, da dieser Vorfahr Teil des Schlüssels ist und es verwendet wird (einige was), wenn Sie eine Abfrage durchführen. –

+1

Jede Entität mit demselben übergeordneten Element befindet sich in der gleichen Entitätsgruppe, und Schreibvorgänge in Entitätsgruppen sind serialisiert. Wenn Sie also hier Vorfahren verwenden, wird dies verlangsamt, wenn Sie mehrere Entitäten gleichzeitig schreiben. Da alle Entitäten in einer Gruppe dem Benutzer gehören, der in Ihrer Instanz den Stamm der Gruppe bildet, sollte dies kein Problem sein - und tatsächlich ist das, was Sie tun, tatsächlich ein empfohlenes Designmuster . –