#google-app-engine #sharding
#google-app-engine #сегментирование
Вопрос:
Мой опыт работы с реляционными базами данных, и я немного экспериментирую с Google AppEngine в первую очередь для обучения. Я хочу создать приложение «выборы», в котором пользователь принадлежит к штату (Калифорния, Нью-Йорк, Техас и т.д.), Они выбирают партию (республиканскую, демократическую и т.д.) И голосуют за определенный год (на данный момент 2012, но приложение может быть повторно использовано в 2016).).
Я хочу, чтобы пользователь мог просматривать историю своих голосований и, возможно, изменять ее один раз для текущих выборов. Кроме того, я собираюсь потребовать, чтобы пользователи указывали свой почтовый индекс, и думаю, было бы неплохо запустить некоторые отчеты по штату и / или почтовому индексу.
Кажется, что при использовании реляционной базы данных вы могли бы создать несколько таблиц, подобных этой:
Users(userid, username, city, state, zip)
UserVote(userid, year, vote)
А затем используйте SQL для запуска отчетов. В хранилище данных AppEngine, похоже, запуск aggregate reports является некоторой проблемой.
Моим первоначальным решением было бы сегментировать по, User
где каждый пользователь может содержать список Votes
, а затем, возможно, дважды сохранить агрегаты в другом месте.
Есть предложения?
PS Я видел проект AppEngine-MapReduce, но не уверен, что это было бы излишеством.
Комментарии:
1. Что вы подразумеваете под «сегментированием пользователем»? Почему mapreduce является излишеством?
2. Что касается «сегментирования пользователем» — исходя из моих ограниченных знаний о хранилище данных, нет способа объединить разные объекты, если только это не иерархические отношения. Тщательный выбор «корневых» объектов (то есть пользователей) позволяет выполнять запросы по связанным объектам. Что касается того, что mapreduce является излишеством — похоже, что это может быть способом вычисления агрегатов, но добавляет дополнительный уровень сложности поверх множества других вещей, которые я пытаюсь изучить.
Ответ №1:
Я не помню точно, где я это читал, но свойства списка в 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
Комментарии:
1. Спасибо за советы! К сожалению, я думаю, что это может быть сценарий, в котором несколько пользователей могут обновлять один и тот же счетчик одновременно : ( (2 пользователя из одного штата голосуют). Я думаю, что, возможно, стоило бы потратить время на то, чтобы все-таки проверить проект mapreduce, но мне нравится ваше предложение отделить
User
отVote
отStats
.2. вы бы сегментировали счетчик. пример см. code.google.com/p/google-app-engine-samples/source/browse/trunk /…