Модель простого обмена сообщениями в App Engine - PullRequest
1 голос
/ 29 ноября 2011

Я работаю над очень простой функцией обмена сообщениями, похожей на электронную почту, как часть приложения App Engine.Это проще, чем электронная почта, в которой нет «строк темы».Другими словами, два пользователя (или больше, но не сотни) могут просто обмениваться сообщениями в цепочке бесед, которая содержит все их сообщения туда и обратно (например, IM, но с цепочкой, которая сохраняется между сеансами).До сих пор я думаю о моделировании этого с двумя типами сущностей: Сообщение и Разговор

class Message(db.Model):
    sender = StringProperty(required=True)
    receiver = StringProperty(required=True)
    message = TextProperty(required=True)
    timestamp = DateTimeProperty(auto_now_add=True)

class Conversation(db.Model):
    messages = ListProperty(int) # List holding the datastore-assigned integer ids of the messages in this conversation
    users = StringListProperty()

Поскольку создание сообщения требует создания или изменения Разговора, я хотел бы сохранить Сообщение и Разговор вта же группа объектов, чтобы эти изменения могли происходить в транзакции.Я подумал, что я буду иметь объекты Message в качестве дочерних элементов связанных с ними объектов Conversation.

Для сообщения требуется ключ для объекта Conversation, чтобы указать его в качестве родителя.Диалогу нужен идентификатор сообщения, чтобы сохранить его в свойстве messages.

Какой самый эффективный способ сделать это?

  • Если у меня есть хранилище данных, назначьте идентификатор дляобъект Conversation, тогда мне нужно (1) поместить объект Conversation в хранилище данных, чтобы получить его идентификатор, (2) поместить объект Message в хранилище данных, чтобы получить его идентификатор, и (3) обновить объект Conversation, чтобы добавить новыйидентификатор сообщения и поместите его снова в хранилище данных.Это требует 3 поездок в хранилище данных, что выглядит неэффективно.
  • Я также мог бы создать уникальное имя ключа для объекта беседы (например, ';'. Join (отсортировано (conv.users)). Делая этоЯ мог бы избежать одной из трех поездок в хранилище данных, описанных выше.

Есть ли способ сделать это с одной поездкой в ​​хранилище данных? Я беспокоюсь о предельном уровне эффективности, которыйЯ действительно не должен беспокоиться о том, есть ли более разумный шаблон дизайна для того, что я собираюсь сделать? Если это так, я был бы очень признателен за указатель.

1 Ответ

4 голосов
/ 29 ноября 2011

Вы инвертируете обычный шаблон дизайна, который будет таким:

class Conversation(db.Model):
    users = StringListProperty()

class Message(db.Model):
    sender = StringProperty(required=True)
    receiver = StringProperty(required=True)
    message = TextProperty(required=True)
    timestamp = DateTimeProperty(auto_now_add=True)
    conversation = db.ReferenceProperty(Conversation)

В приведенной выше модели вам не нужно изменять объект диалога при сохранении нового сообщения, если только вы не обновляете список пользователей. Я бы рекомендовал использовать это, если нет причин не делать этого.

Это также должно быть немного более масштабируемым. Если ваш разговор достигает 1000 сообщений, вам не нужно хранить 1000 свойств идентификатора сообщения в одном объекте разговора.

Предположим, однако, что вы хотите сохранить свою оригинальную модель. Чтобы сохранить беседу и сообщение в одной поездке, вам необходимо назначить идентификатор сообщения. Мой совет здесь заключается в том, чтобы сгенерировать UUID (например, с uuid.uuid4()) и назначить его в качестве имени ключа сообщения (и добавить его в список сообщений), а не ждать, пока хранилище данных назначит идентификатор.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...