Я хочу реализовать интернет-рекорды для своей игры. И дайте отзывы игрокам, которые у них есть (не только top100, либо что-то в этом роде). В обычном SQL это будет выглядеть так:
SELECT COUNT (*) FROM Scores WHERE points > : newUsersPoints
и GQL имеют нечто подобное
db.GqlQuery( "SELECT * FROM Score WHERE points > : 1", newUsersPoints).count()
но поскольку count() ограничен только 1000, это не будет очень полезно в моем случае. У вас есть идеи о том, как это реализовать?
У меня есть два
Во-первых:
-
Используйте идею счётчиков (http://code.google.com/intl/pl/appengine/articles/sharding_counters.html) Создайте новую "таблицу", в которой хранится количество баллов в некотором диапазоне (from_points, to_points)
-
Суммируйте все счетчики из таблицы выше, где range.to_points < newUsersPoints
-
Найдите, сколько очков больше, чем баллы в диапазоне, где новый счет db.GqlQuery( "SELECT * FROM Score WHERE points > : 1 AND points > =: 2 AND points <: 3", newUsersPoints, range.from_points, range.to_points).count() + sumfrom2
-
Найдите диапазон, в котором находится новый балл, и увеличивайте его счетчик
-
Диапазоны разделения, для которых счетчик больше 1000 (или 999), так что 3. не достигнет предела
-
Добавить новый счет в таблицу баллов
Это довольно сложно и подвержено ошибкам. Мы можем увеличить диапазон и время ожидания до добавления оценки. (не транзакционный)
Вторая идея:
Время от времени (один раз в день?) сортировать все баллы по точкам и давать им новые позиции (script может Timeout, поэтому мы должны делать это в кусках)
Чтобы узнать, в каком месте новый счет, мы просто делаем
db.GqlQuery( "SELECT * FROM Score WHERE points > : 1 LIMIT 1", newUsersPoints).get(). precalculated_position + 1
Любые другие идеи?