использование реляционной базы данных для хранения результатов игр один на один (-to-head) - PullRequest
0 голосов
/ 23 января 2011

У меня есть сайт, где люди записывают результаты игр.95% игр проводятся в одиночку, но 5%, которые не отбрасывают статистику выигрыш-ничья-выигрыш для каждого сценария.

Каждое сражение имеет 2 стороны, и все возможные результаты:

  • Сторона 1 выигрывает
  • Сторона 2 выигрывает
  • Ничья

Если 2 человека играют друг друга, и оба записывают игру, вы получаете2 победы для данной стороны, когда должна быть только одна (имеет смысл?), И это сбрасывает рейтинг баланса.Эти записи должны быть объединены, когда придет время отображать статистику битвы.

Мой первоначальный kludge заключался в том, чтобы программировать PHP таким образом, чтобы та же дата воспроизведения + тот же результат = группа в один только результат ,тем не менее, по мере роста количества пользователей (люди, играющие в один и тот же день и случайно получающие тот же результат), становятся все более частыми.

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

В настоящее время все записи хранятся в одной таблице battle_results, которая имеет следующую структуру:

[play_id] [user_id] [battle_id] [play_date] [win_side]
  000001    007       DeRa001    2010-01-01     1
  000002    010       DeRa001    2010-01-01     1

Я хочу дать своим пользователям возможность перечислять, играли ли они соло или один на один, и на какой стороне они играли, поэтому я планирую изменить стол следующим образом:

[play_id] [user_id] [battle_id] [play_date] [win_side] [play_type] [user_side]
  000001    007       DeRa001    2010-01-01    1           multi        2
  000002    010       DeRa001    2010-01-01    1           multi        1

это достаточно просто.Но пользователи должны быть в состоянии сказать, с кем они играли.Сначала я думал, что таблица «многие ко многим» справится с задачей:

[play_id] [user_id] [opponent_id]
  00001     007        010

, но потом я понял, что когда противник отправит ту же запись, вы просто поменяете местами столбцы:

[play_id] [user_id] [opponent_id]
  00001     007        010
  00002     010        007

и я действительно понятия не имею, как извлечь эти данные и построить соотношение выигрыша и выигрыша, которое признало бы, что все эти люди играют вместе ...

Имею ли я смысл?Как мне сопоставить эти записи?

Ответы [ 2 ]

1 голос
/ 23 января 2011

Я бы сделал это немного по-другому.

Я предполагаю, что у вас есть стол battle, и для каждого сражения может быть несколько игр, в которых два человека играют вместе.

battle_results будет содержать:

play_id   battle_id   play_date    play_type
      1     DeRa001   2011-01-01       multi

Теперь вам нужна новая таблица participants, в которой перечислены участники каждой игры:

play_id user_id is_winner position
      1     007         0    Side1
      1     010         1    Side2

Эта таблица будет иметь (play_id, user_id) в качестве первичного ключа, поэтому один и тот же пользователь не может играть дважды для одной и той же игры (это решает проблему, заключающуюся в том, что одну и ту же комбинацию можно вставить дважды с другим «направлением». Обратите внимание, что play_id уникален для сингла , поэтому у вас всегда будет две строки с одинаковым play_id.

Редактировать: вы можете указать ничью, установив is_winner в 0 для всех участников игры.

Чтобы выяснить, с кем играл конкретный пользователь (например, 007), просто:

SELECT user_id 
FROM participants
WHERE play_id IN (SELECT p2.play_id
                    FROM participants p2
                   WHERE p2.user_id = '007')

Чтобы найти общее количество побед для пользователя:

SELECT count(*)
FROM participants
WHERE user_id = '007'
AND is_winner = 1

Чтобы найти соотношение выигрыша / проигрыша:

SELECT total_loss / total_wins
FROM ( 
  SELECT user_id, 
         count(CASE WHEN is_winner = 0 THEN 1 ELSE NULL) as total_loss, 
         count(CASE WHEN is_winner = 1 THEN 1 ELSE NULL) as total_wins
  FROM participants
) T
WHERE user_id = '007'
0 голосов
/ 23 января 2011

Что не так с хранением таких данных:

[battle_id] [opponent_1] [opponent_2] [result_1] [result_2]
    1            007         010          1          0
    2            011         007          0          1
    3            007         012          0          0

ищет 007 выигрышей игрока (результат 2):

select count(*) from battles 
where 
   (opponent_1 = '007' AND result_1 = 1 and result_2 = 0) 
   OR 
   (opponent_2 = '007' AND result_1 = 0 and result_2 = 1)

ищет игроков 007 ничьи(результат 1):

select count(*) from battles 
where 
     (opponent_1 = '007' AND result_1 = 0 and result_2 = 0) 
     OR 
     (opponent_2 = '007' AND result_1 = 0 and result_2 = 0)

и т. д.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...