Pregunta

Problema de ejemplo:

Entidades:

  • El usuario contiene el nombre y una lista de amigos (referencias de usuario)
  • La publicación del blog contiene título, contenido, fecha y escritor (usuario)

Requisito:

Quiero una página que muestre el título y un enlace al blog de las últimas 10 publicaciones del amigo de un usuario. También me gustaría la posibilidad de seguir buscando en las entradas más antiguas.

Solución SQL:

Entonces, en tierra sql sería algo así como:

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

Las soluciones GAE que se me ocurren son:

  • Cargar usuario, recorrer la lista de amigos y cargar sus últimas publicaciones de blog. Finalmente, combine todas las publicaciones de blog para encontrar las últimas 10 entradas de blog
  • En una publicación de blog, tenga una lista de todos los usuarios que tienen al escritor como amigo. Esto significaría una lectura simple pero daría lugar a una sobrecarga de cuotas al agregar un amigo que tiene muchas publicaciones en el blog.

No creo que ninguna de estas soluciones vaya a escalar.

Estoy seguro de que otros han tenido este problema, pero he buscado, visto videos de google io, leí el código de otros ... ¿Qué me estoy perdiendo?

¿Fue útil?

Solución 2

Este tema se trata en una charla io de Google: http://code.google.com/events/io/sessions/BuildingScalableComplexApps. html

Básicamente, el equipo de Google sugiere utilizar las propiedades de la lista y lo que llaman entidades de índice relacional, aquí se puede encontrar una aplicación de ejemplo: http://pubsub-test.appspot.com/

Otros consejos

Si observa cómo se ejecutará la solución SQL que proporcionó, básicamente será así:

  1. Obtener una lista de amigos para el usuario actual
  2. Para cada usuario en la lista, inicie un análisis de índice de publicaciones recientes
  3. Combinar y unir todos los escaneos del paso 2, deteniéndose cuando haya recuperado suficientes entradas

Puede realizar exactamente el mismo procedimiento en App Engine, utilizando las instancias de consulta como iteradores y uniendo una combinación sobre ellas.

Tiene razón en que esto no escalará bien a un gran número de amigos, pero sufre exactamente los mismos problemas que tiene la implementación de SQL, simplemente no los disfraza también: Recuperando los últimos 20 (por ejemplo) las entradas cuestan aproximadamente O (n log n) trabajo, donde n es el número de amigos.

" Cargar usuario, recorrer la lista de amigos y cargar sus últimas publicaciones en el blog. "

Eso es todo lo que una unión es: bucles anidados. Algunos tipos de combinaciones son bucles con búsquedas. La mayoría de las búsquedas son solo bucles; algunos son hashes.

" Finalmente, combine todas las publicaciones del blog para encontrar las últimas 10 entradas de blog "

Eso es un ORDENADO CON un LÍMITE Eso es lo que la base de datos está haciendo por usted.

No estoy seguro de qué no es escalable sobre esto; es lo que hace una base de datos de todos modos.

Aquí hay un ejemplo en python obtenido de http://pubsub-test.appspot.com/:

¿Alguien tiene uno para Java? Gracias.

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))
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top