Список ключей или отдельная модель? - PullRequest
2 голосов
/ 28 марта 2012

Я создаю приложение с пользователями и их действиями.Сейчас я думаю о лучшем способе настройки моделей хранилища данных.Какой из них самый быстрый / предпочтительный и почему?

A

class User(db.Model):
    activities = db.ListProperty(db.Key)
    ...
class Activity(db.Model):
    ...

activities = db.get(user.activities)

или

B

class User(db.Model):
    ...
class Activity(db.Model):
    owner = db.ReferenceProperty(reference_class=User)
    ...

activities = Activity.filter('owner =', user)

Ответы [ 5 ]

2 голосов
/ 28 марта 2012

Если у данного действия может быть только один владелец, обязательно используйте ReferenceProperty.

  • Это то, для чего ReferenceProperty s предназначены для
  • . Оно будет автоматически установленообратные ссылки для вас, что может быть удобно, так как дает двунаправленную ссылку (в отличие от ListProperty, которая является однонаправленной ссылкой)
  • Он обеспечивает, что объект, с которым связана ссылка, являетсяправильный тип / класс
  • Он обеспечивает, что только один пользователь связан с данным действием
  • Он позволяет автоматически извлекать связанные объекты без необходимости писать явный запрос, если вы этого хотите
0 голосов
/ 28 марта 2012

Как насчет C: установка родителя Activity в ключ пользователя? Чтобы вы могли получать действия пользователя с помощью Activity.query (ancestor = user.key).

Таким образом, вам не нужны дополнительные ключи / свойства + хороший способ сгруппировать ваши сущности для хранилища данных HR.

0 голосов
/ 28 марта 2012

A будет намного быстрее, потому что он работает исключительно с ключами. Поиск объектов с помощью только ключей идет прямо к узлу данных в BigTable, в то время как B сначала требует поиск по индексам, который идет медленнее (и затраты возрастут с увеличением количества объектов Activity).

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

0 голосов
/ 28 марта 2012

Я не знаю о разнице в производительности, я подозреваю, что она будет похожей. Когда дело доходит до совершенства, с хранилищем данных GAE сложно справиться. Если все ваши запросы попадают на один и тот же планшет (большой сервер), это может ограничить вашу производительность больше, чем сам запрос.

Большая разница в том, что A будет дешевле, чем B. Поскольку у вас есть список действий, которые вы хотите, вам не нужно писать индекс для каждого объекта деятельности, который вы пишете. Если действия написаны много, ваши сбережения складываются.

Поскольку у вас есть ключ активности, у вас также есть возможность выполнять высокосогласованный метод get (), а не в конечном итоге согласованный фильтр ()

С другой стороны, вы не сможете делать обратные ссылки, как, например, искать владельца по заданию. Ваше свойство ListProperty также может привести к тому, что вы достигнете своего максимального размера объекта - со временем будет жесткое ограничение на количество действий на пользователя. Если вы пошли с B, вы можете иметь огромное количество действий на пользователя.

Редактировать: я забыл, у вас может обратная ссылка, если вы индексируете свой ListProperty, но тогда написание вашего объекта User будет дорогостоящим, а ограничение на количество индексированных свойств будет ограничивать размер вашего списка. Поэтому, даже если это возможно, B все еще предпочтительнее, если вам нужны обратные ссылки.

0 голосов
/ 28 марта 2012

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

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

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

С учетом всего сказанного, я был бы удивлен, если бы у вас была заметная разница между этими двумя подходами. Область, где вы получите гораздо более заметные улучшения производительности, - это использование memcache.

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