MySQL и оперирование с рейтингом игроков

Допустим есть табличка с игроками, где у каждого игрока есть поле «score».

И мы хотим создать общий рейтинг игроков с сортировкой по этому полю.

Вопрос в том, можно ли как-то получить позицию заданного игрока в этом рейтинге? Т.е. есть игрок со score=12 и при сортировке по этому полю он будет в списке всех игроков на 50000-м месте.

Можно как-то определить это самое место легким движением руки?

Или вариант тут только один — раз в N времени выполнять проход по отсортированной таблице и запоминать рейтинги?

Объемы данных планируются от 100 тыс. юзеров до миллиона. Каким вообще образом создаются отсортированные рейтинги при таких больших объемах?
  • Вопрос задан
  • 4474 просмотра
Пригласить эксперта
Ответы на вопрос 7
@SSoft
Пусть есть таблица table: id, PlayerName, score

есть данные:

1 player1 12
2 player2 15
3 player3 14
4 player4 14
5 payer5 15
6 player6 12

SELECT COUNT(DISTINCT score) as position FROM table WHERE score >= (SELECT score FROM table WHERE PlayerName='player1' LIMIT 1)

Результат будет:

SELECT COUNT(DISTINCT score) FROM table WHERE score >= 12

15
count = 14 = 3 = position
12
Ответ написан
kashey
@kashey
Программирую большую половину жизни
UPDATE table SET spore=spore+1/rand(1,10000000000000)
берем и молча добавляет флуктуацию после запятой.
Если у вас spore — определена до 0.001 например — определите флуктуацию как 0.001\rand

Как вариант — фиксиовать эту флуктуацию на определенного юзера при создании этого самого пользователя.

Ну это детали.
Главное — в том что вы всегда можете выполнить

SELECT COUNT(*) FROM table WHERE spore<?

И получить точное значение, даже если ищем spore=12 и этих 12 несколько сотен тысяч
Ответ написан
netAn
@netAn
Дальше пятидесятой позиции не так важно — какая именно по счету позиция у геймера. Поэтому часто обновлять «по честному» рейтинг имеет смысл для top50, где идёт рубка между самыми ярыми фанатами игры за первое место.
далее — движение по рейтингу не будет резким и будет кратно времени одной игры (интервал обновления рейтинга одного игрока) и не скакнет дальше среднего числа очков за один сеанс. Таким образом, рейтинги можно обновлять «на глаз» и бить их по группам.
Это уж если игроков совсем миллионы.
Но одновременно онлайн будут максимум сотни, так что сильно не мучайтесь оптимизацией этой таблицы.
А когда одновременно играть будут тысячи, сделаете рефакторинг кода и баз, а может и смените сервер.
Ответ написан
justabaka
@justabaka
Оффтопик: если юзеров планируется действительно так много, то лучше использовать разбиение на дивизионы/лиги, чем показывать «чистое» место. Мало кому приятно видеть, что он на 239676 месте.
Ответ написан
@torsten
партиционировать таблицу по полю score
тогда COUNT(*) FROM table WHERE score<? будет выполняться с использованием primary key на каждой из партиций, что должно работать очень быстро
)
Ответ написан
Можно создать переменную.

SELECT *, (@position:=@position+1) FROM `users`, (SELECT @position:=0) `a` WHERE 1
Ответ написан
Но лучше «Или вариант тут только один — раз в N времени выполнять проход по отсортированной таблице и запоминать рейтинги?»
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы