Мне нужна страница, которая отображает заголовок и ссылку на блог последних 10 сообщений друга пользователя. Я также хотел бы иметь возможность просматривать старые записи.
Итак, в sql land это будет примерно так:
select * from blog_post where user_id in (select friend_id from user_friend where user_id = :userId) order by date
Я не верю, что ни одно из этих решений будет масштабным.
Я уверен, что другие сталкивались с этой проблемой, но я искал, смотрел видео в Google io, читал чужой код ... Что мне не хватает?






Если вы посмотрите, как будет выполняться предоставленное вами решение SQL, оно будет выглядеть примерно так:
Вы можете самостоятельно выполнить ту же процедуру в App Engine, используя экземпляры Query в качестве итераторов и выполняя над ними объединение слиянием.
Вы правы, что это не будет хорошо масштабироваться для большого количества друзей, но оно страдает от тех же проблем, что и реализация SQL, просто не маскирует их: получение последних 20 (например) записей стоит примерно O (n log n) work, где n - количество друзей.
В значительной степени да. Если вам нужно 20 или меньше результатов, я бы предложил просто получить первые 20 результатов от каждого пользователя, отсортировать и взять первые 20 результатов. Если вы хотите большего, реализуйте правильную сортировку слиянием, используя запросы в качестве итераторов.
«Загрузите пользователя, пролистайте список друзей и загрузите их последние сообщения в блоге».
Вот и все соединение - вложенные циклы. Некоторые виды соединений представляют собой циклы с поиском. Большинство поисков - это просто циклы; некоторые - хеши.
"Наконец, объедините все сообщения в блоге, чтобы найти последние 10 записей в блоге"
Это ЗАКАЗ с ПРЕДЕЛОМ. Вот что делает за вас база данных.
Я не уверен, что в этом не масштабируется; в любом случае это то, что делает база данных.
Да, но база данных ЗНАЕТ, что это делает. Следовательно, он может его оптимизировать.
Эта тема рассматривается в Google io talk: http://code.google.com/events/io/sessions/BuildingScalableComplexApps.html
В основном команда Google предлагает использовать свойства списка и то, что они называют объектами реляционного индекса, пример приложения можно найти здесь: http://pubsub-test.appspot.com/
Вот пример на python из http://pubsub-test.appspot.com/:
У кого-нибудь есть для java? Спасибо.
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))
Поэтому, если мне нужна эта функция, я должен зацикливаться и отсортировать себя, взять любое требуемое попадание в процессор и кэшировать результаты. Это будет считаться «лучшей практикой»?