Есть ли способ сделать совокупные функции в Google App Engine?

Одной из хороших возможностей поддержки реляционных баз данных являются агрегированные функции, такие как count, sum, avg и т.д. Но кажется, что если вы используете GAE, при вставке или обновлении записи вы должны вычислять и хранить счет, сумму, avg и т.д. значения всей таблицы. Но что, если у вас много условных группировок? Учитывая человека:

class Person {
    @Id
    Integer age;
    String city;
}

Если я хочу

  • общее число лиц и
  • средний возраст

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

Ответ 1

Правильно: для правильного использования хранилища GAE вам необходимо выборочно де-нормализовать некоторые аспекты вашей модели, сохраняя "избыточные" данные, которые в DB в нормальной форме вы перекомпонуете "на лету", например, агрегаты ( общий и "сгруппированный по" ).

Однако не добавляйте такие поля в таблицу Person в вашем случае - это мало смысла! Создайте еще одну таблицу PersonAggregates с такими столбцами, как City (null/missing для общих итогов), Count, TotalAges (проще в обслуживании: вычислить среднее значение в любое время как общее количество по счету).

Ответ 2

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

Если вы не создали такие агрегаты в своем приложении с самого начала, вы можете запустить script через Remote DataStore API или настроить серверную задание cron, которое будет обрабатывать все сущности и вычислять агрегаты. Это довольно просто, просто помните о квоте процессора для каждого запроса.