Нужны советы по денормализации для Google App Engine - PullRequest
2 голосов
/ 06 февраля 2011

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

В системе будут пользователи, с данными профиля и изображением.Эти пользователи смогут создавать «события» и добавлять в него записи журнала.Для целей системы «события», скорее всего, будут содержать 1 или 2 записи в журнале, и что-либо более 10, вероятно, никогда не произойдет.Другие пользователи также смогут добавлять комментарии к записям пользователей, где популярные могут содержать сотни или даже тысячи комментариев.Когда случайный посетитель использует систему, он должен иметь возможность видеть последние события (последние, определяемые событиями с последними записями в журнале), выполнять поиск по тегу и выполнять базовый текстовый поиск.Затем, после выбора события для просмотра, оно должно отображаться со всеми записями журнала и всеми комментариями пользователей, с изображениями пользователей вместе с комментариями.У пользователя также должна быть своего рода страница для самостоятельного администрирования, позволяющая просматривать / изменять / удалять свои события и просматривать / изменять / удалять комментарии, которые они делали в отношении других событий.Таким образом, выполнение всего этого на обычной СУБД будет просто запрашивать несколько больших объединений в нескольких таблицах.На GAE это, очевидно, должно работать по-другому.Вот мои первые мысли о дизайне сущностей:

  • Сущность события - идентификатор, имя, отметка времени, свойство списка тегов, количество просмотров, имя пользователя создателя, идентификатор изображения профиля создателя, количество записей в журнале.он содержит, общее количество комментариев, которые он содержит, отметку времени последнего обновления содержащихся записей журнала, свойство списка индексных слов для поиска (построено / обновлено на основе текста из содержащихся записей журнала)
  • Объект JournalEntry - отметка времени, текст журнала, имя события, имя пользователя создателя, идентификатор изображения профиля создателя, свойство списка комментариев (содержащее имя пользователя и идентификатор изображения комментатора)
  • Сущность пользователя - имя пользователя, хэш пароля, адрес электронной почты, свойство списка подписанных событий, отметка времени созданиядата, идентификатор изображения, количество опубликованных комментариев, количество созданных событий, количество созданных записей журнала, отметка времени последней активности журнала
  • Объект UserComment - имя пользователя, идентификатор комментария к событию, комментарий к событию, отмеченному
  • Сущность TagData - таg name, количество событий с тегами

Итак, я хотел бы услышать, что люди думают о дизайне и какие изменения нужно внести, чтобы он хорошо масштабировался.Спасибо!

1 Ответ

8 голосов
/ 06 февраля 2011
  • Вместо того, чтобы хранить Event.id в качестве свойства, используйте идентификатор, автоматически встроенный в ключ каждой сущности, или задайте уникальные имена ключей для сущностей при их создании.
  • У вас есть много вариантов для моделирования отношений между Event и JournalEntry: вы можете использовать ReferenceProperty, вы можете указать от JournalEntries до Events и получить их с помощью запросов предков, или вы можете сохранить список JournalEntry идентификаторов клавиш или имен в Event и получение их в пакетном режиме с помощью запроса ключа. Попробуйте кое-что с реалистично распределенными фиктивными данными и используйте appstats , чтобы увидеть, что работает лучше.
  • UserComment ссылается на Event, а JournalEntry ссылается на список UserComments, что немного сбивает с толку. Есть ли связь между UserComment и JournalEntry? или только между UserComment и Event?
  • Сохранение такого количества счетов дорого. Когда я оставляю комментарий, вы собираетесь написать новую сущность UserComment, а также обновить мою сущность User, сущность JournalEntry и сущность Event. Число UserComments, которое вы ожидаете на Event, делает неразумным включение всего в одну группу сущностей, что означает, что вы не можете выполнять эти записи транзакционно, поэтому вы будете делать их последовательно, и сущности могут храниться в разных местах. различные узлы сети, что делает всю работу медленной; и вы также будете открыты для проблем согласованности. Можете ли вы обойтись без некоторых из этих подсчетов и рассмотреть возможность хранения других в memcache?
  • Когда вы извлекаете Event из хранилища данных, вы на самом деле не заботитесь о его списке слов индекса поиска, и получение и десериализация их из буферов протокола требует затрат. Это можно обойти, разбив каждое слово индекса поиска Event на отдельный дочерний объект EventIndex. Затем вы можете запросить EventIndex по вашему поисковому запросу, получить только ключи EventIndex для EventIndexes, которые соответствуют вашему поиску, получить соответствующие Events 'ключи с key.parent() и извлечь Events по ключу, никогда не платите за поиск или десериализацию ваших списков слов индекса поиска. Бретт Слаткин объясняет эту стратегию здесь в 14: 35.
  • Обновление Event.viewCount завершится неудачей, если у вас есть много просмотров для любого Event в быстрой последовательности, поэтому вы должны попробовать счетчик sharding .

Удачи, и расскажите нам, что вы узнали, попробовав что-то.

...