2009-06-14 15 views
11

Eines der schönen Dinge, die relationale Datenbanken unterstützen, sind die Aggregatfunktionen wie count, sum, avg usw. Aber wenn Sie GAE verwenden, müssen Sie beim Einfügen oder Aktualisieren eines Datensatzes die Anzahl, Summe, Durchschnitt, usw. Werte der ganzen Tabelle. Aber was, wenn Sie viele bedingte Gruppierungen haben? Bei einer Person:Gibt es eine Möglichkeit, Aggregatfunktionen in Google App Engine auszuführen?

class Person { 
    @Id 
    Integer age; 
    String city; 
} 

Wenn ich will

  1. die Gesamtzahl der Personen und
  2. das Durchschnittsalter

Ist es richtig, dass jedes Mal wenn ich erstellen, aktualisieren oder löschen Eine Person Ich sollte auch beide Aggregate berechnen und sie als separate Spalten in der gleichen Tabelle speichern. Wenn ich auch die Gesamt- und Durchschnittswerte pro Stadt haben möchte, sollte ich diese Werte für jede Stadt auch als separate Spalten in derselben Tabelle speichern?

Antwort

6

Rechts: Um GAE-Speicher richtig zu verwenden, müssen Sie einige Aspekte Ihres Modells selektiv de-normalisieren, indem Sie "redundante" Daten behalten, die Sie in einer Datenbank in normaler Form im Handumdrehen neu berechnen würden (insgesamt und "gruppiert nach").

Allerdings fügen Sie solche Felder nicht zur Person Tabelle in Ihrem Fall hinzu - das macht wenig Sinn! Machen Sie eine weitere Tabelle mit Spalten wie Stadt (null/fehlt für Gesamtsummen), Count, TotalAges (einfacher zu pflegen: berechnen Sie den Durchschnitt zu jeder Zeit als Summe geteilt durch Anzahl).

+0

Das klingt unglaublich teuer, sowohl in Softwareentwicklungszeiten als auch in CPU-Gebühren. Ich muss denken, dass sich Google aus gutem Grund dem Datenspeicher nähert, aber meine erste Reaktion ist Horror. Alex, was ist ein gutes Best-Practice-Buch oder Dokument, das du SQL-Heavy-Typen wie mich empfehlen würdest? –

+0

Ausgezeichnete Frage, und ich freue mich zu sehen, dass ich eine gute Annäherung wählte, indem ich eine Art nur für die Aggregation schuf. Wie jedoch @JD sagt, kann das Implementieren dieser Aggregation teuer und fehleranfällig sein. Ich habe keine Eigenschaft für diese gefunden (etwas wie 'totalAge = db.AggregateProperty (of = Person.age)'. Was denkst du ist der beste Ansatz? – rds

+0

Ich habe gerade gefunden http://code.google.com/ appengine/articles/sharding_counters.html – rds

3

Für häufig verwendete Aggregate ist es am besten, sie bei jedem Update/Einfügen/Löschen zu aktualisieren.

Wenn Sie nicht solche Aggregate in Ihre Anwendung von Anfang an entworfen haben, können Sie ein Skript über Remote DataStore API oder stellen Sie einen serverseitigen cron job laufen, das alle Einheiten verarbeiten und die Aggregate berechnen. Es ist ziemlich einfach, denken Sie nur an die CPU-Quote pro Anfrage.

Verwandte Themen