Frage

Beispiel Probleme:

Instanzen:

  • Benutzer enthält Namen und eine Liste der Freunde (User Referenzen)
  • Blogbeitrag enthält Titel, Inhalt, Datum und Verfasser (Benutzer)

Anforderung:

Ich möchte eine Seite, die den Titel und einen Link zu dem Blog der letzten 10 Beiträge eines Benutzers Freund zeigt. Ich möchte auch die Möglichkeit, einen Funkruf zu halten zurück durch ältere Einträge.

SQL Lösung:

So in SQL-Land wäre es so etwas wie:

select * from blog_post where user_id in (select friend_id from user_friend where user_id = :userId) order by date

GAE Lösungen kann ich denken sind:

  • Laden Benutzer, Schleife durch die Liste der Freunde und ihre neuesten Blog-Posts laden. Schließlich verschmelzen alle Blog-Beiträge die neuesten 10 Blog-Einträge finden
  • In einer Blog-Post hat eine Liste aller Benutzer, die den Schriftsteller als Freund haben. Dies würde eine einfache Lese bedeutet aber in Quote Überlastung führen würde, wenn ein Freund hinzugefügt, die viele Blog-Beiträge.

Ich glaube nicht, eine dieser Lösungen skalieren.

Im anderen sicher dieses Problem getroffen haben, aber ich gesucht haben, sah io Videos google, lesen Sie anderen Code ... Was bin ich?

War es hilfreich?

Lösung 2

Dieses Thema wird in einem Google-io Vortrag behandelt: http://code.google.com/events/io/sessions/BuildingScalableComplexApps. html

Im Grunde das Google-Team vorschlagen Liste Eigenschaften verwenden und was sie relationalen Index Entitäten nennen, kann eine Beispielanwendung finden Sie hier:

Andere Tipps

Wenn man sich anschaut, wie die SQL-Lösung, die Sie ausgeführt wird zur Verfügung gestellt wird, wird es im Grunde so:

  1. Holt eine Liste von Freunden für den aktuellen Benutzer
  2. Für jeden Benutzer in der Liste, einen Index-Scan in den letzten Beiträgen beginnen
  3. Merge-Join alle Scans von Schritt 2 zu stoppen, wenn Sie genug Einträge
  4. abgerufen haben

Sie können genau die gleiche Prozedur selbst in App Engine durchführen, indem Sie die Abfrage-Instanzen als Iteratoren verwenden und dabei eine Zusammenführung über anzuschließen.

Sie haben Recht, dass dies nicht gut für eine große Anzahl von Freunden skaliert, aber es leidet an genau den gleichen Problemen der SQL-Implementierung hat, es hat sie nur nicht darüber hinwegtäuschen, wie auch: Holen der letzten 20 (zum Beispiel) Einträge kosten etwa O (n log n) Arbeit, wobei n die Anzahl der Freunde.

"Load Benutzer, Schleife durch die Liste der Freunde und ihre neuesten Blog-Posts laden."

Das ist alles eine Join - verschachtelte Schleifen. Einige Arten von Joins sind Schleifen mit Lookups. Die meisten Lookups sind nur Schleifen; einige sind Hashes.

„Schließlich verschmelzen alle Blog-Beiträge die neuesten 10 Blog-Einträge zu finden“

Das ist eine ORDER BY mit einem LIMIT. Das ist, was die Datenbank für Sie tut.

Ich bin mir nicht sicher, was diese nicht skalierbar ist; es ist, was eine Datenbank tut es trotzdem.

Hier ist ein Beispiel in Python schimmerte von http://pubsub-test.appspot.com/:

Wer noch einen für Java? Danke.

from google.appengine.ext import webapp

from google.appengine.ext import db

class Message(db.Model):
 body = db.TextProperty(required=True)
 sender = db.StringProperty(required=True)
 receiver_id = db.ListProperty(int)

class SlimMessage(db.Model):
 body = db.TextProperty(required=True)
 sender = db.StringProperty(required=True)

class MessageIndex(db.Model):  
 receiver_id = db.ListProperty(int)

class MainHandler(webapp.RequestHandler):

 def get(self):
  receiver_id = int(self.request.get('receiver_id', '1'))
  key_only = self.request.get('key_only').lower() == 'on'
  if receiver_id:
    if key_only:
      keys = db.GqlQuery(
          'SELECT __key__ FROM MessageIndex WHERE receiver_id = :1',
          receiver_id).fetch(10)
      messages.extend(db.get([k.parent() for k in keys]))
    else:
      messages.extend(Message.gql('WHERE receiver_id = :1',
                      receiver_id).fetch(10))
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top