Сведения о вопросе

Henry

09:31, 17th August, 2020

Теги

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

Просмотров: 479   Ответов: 7

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

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

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

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

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

Объемы данных планируются от 100 тыс. юзеров до миллиона. Каким вообще образом создаются отсортированные рейтинги при таких больших объемах?



  Сведения об ответе

appple

15:05, 14th August, 2020

Пусть есть таблица 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


  Сведения об ответе

#hash

11:13, 20th August, 2020

UPDATE table SET spore=spore+1/rand(1,10000000000000)
берем и молча добавляет флуктуацию после запятой.
Если у вас spore — определена до 0.001 например — определите флуктуацию как 0.001\rand

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

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

SELECT COUNT(*) FROM table WHERE spore<?

И получить точное значение, даже если ищем spore=12 и этих 12 несколько сотен тысяч


  Сведения об ответе

LIZA

18:37, 18th August, 2020

Дальше пятидесятой позиции не так важно — какая именно по счету позиция у геймера. Поэтому часто обновлять «по честному» рейтинг имеет смысл для top50, где идёт рубка между самыми ярыми фанатами игры за первое место.
далее — движение по рейтингу не будет резким и будет кратно времени одной игры (интервал обновления рейтинга одного игрока) и не скакнет дальше среднего числа очков за один сеанс. Таким образом, рейтинги можно обновлять «на глаз» и бить их по группам.
Это уж если игроков совсем миллионы.
Но одновременно онлайн будут максимум сотни, так что сильно не мучайтесь оптимизацией этой таблицы.
А когда одновременно играть будут тысячи, сделаете рефакторинг кода и баз, а может и смените сервер.


  Сведения об ответе

#hash

15:36, 29th August, 2020

Оффтопик: если юзеров планируется действительно так много, то лучше использовать разбиение на дивизионы/лиги, чем показывать «чистое» место. Мало кому приятно видеть, что он на 239676 месте.


  Сведения об ответе

darknet

04:49, 9th August, 2020

партиционировать таблицу по полю score
тогда COUNT(*) FROM table WHERE score<? будет выполняться с использованием primary key на каждой из партиций, что должно работать очень быстро
)


  Сведения об ответе

lesha

16:34, 12th August, 2020

Можно создать переменную.


SELECT *, (@position:=@position+1) FROM `users`, (SELECT @position:=0) `a` WHERE 1


  Сведения об ответе

SEEYOU

03:42, 3rd August, 2020

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


Ответить на вопрос

Чтобы ответить на вопрос вам нужно войти в систему или зарегистрироваться