Вопрос об использовании Google AppEngine - PullRequest
2 голосов
/ 31 мая 2011

Мой опыт работы в реляционных БД, и я немного экспериментирую с Google AppEngine, в первую очередь для обучения. Я хочу создать «избирательное» приложение, в котором пользователь принадлежит государству (Калифорния, Нью-Йорк, Техас и т. Д.), Выбирает партию (республиканец, демократ и т. Д.) И голосует за определенный год (пока что 2012, но приложение может быть повторно использовано в 2016 году).

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

Используя реляционную БД, кажется, вы бы создали несколько таблиц, подобных этой:

Users(userid, username, city, state, zip)
UserVote(userid, year, vote)

А затем используйте SQL для запуска отчетов. С хранилищем данных AppEngine кажется, что запускать сводные отчеты довольно сложно.

Мое первоначальное решение было бы разделить на User, где каждый пользователь может содержать список Votes, а затем, возможно, дважды сохранить агрегаты в другом месте.

Есть предложения?

P.S. Я видел проект AppEngine-MapReduce , но не уверен, что это излишне.

1 Ответ

1 голос
/ 31 мая 2011

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

Агрегаты являются проблемой, так как нет таких общих вспомогательных функций, как MAX, SUM, COUNT и так далее. Наилучшим подходом было бы хранить агрегаты и подсчеты в отдельном типе данных, который можно легко запрашивать и обновлять каждый раз, когда пользователь голосует. В AppEngine проще тратить время, когда вы пишете, чтобы у вас могли быть более быстрые запросы позже.

Вот пример объектов в Java:

@PersistenceCapable
public class User{
    @PrimaryKey
    @Persistent(valueStrategy = IdGeneratorStrategy.IDENTITY)
    private Key key;
    ...
}

@PersistenceCapable
public class Vote{
    @PrimaryKey
    @Persistent(valueStrategy = IdGeneratorStrategy.IDENTITY)
    private Key key;

    @Persistent
    private Key userKey;  // References a User
    ...
}

@PersistenceCapable
public class UserStats{
    @PrimaryKey
    @Persistent(valueStrategy = IdGeneratorStrategy.IDENTITY)
    private Key key;

    @Persistent
    private Key userKey;  // References a User
    ...
}

Кроме того, традиционное разбиение не имеет особого смысла в AppEngine, поскольку базовое хранилище данных предназначено для простой обработки запросов к массивам данных. Исключение составляют случаи, когда у вас есть определенный счетчик, который можно часто менять и который может измениться одновременно несколькими пользователями. Это другой тип шардинга, чем вы привыкли в MySQL. Вот статья Google о счетчиках шардинга: http://code.google.com/appengine/articles/sharding_counters.html

...