Я регулярно играю в игру 2 на 2 с 12 друзьями и хочу, чтобы база данных отслеживала игроков, команды, результаты и игры с целью создания системы рейтинга.
Поскольку мы регулярно меняем команды, я придумал таблицы players
, teams
и games
в играх было две команды (team1 и team2), а команды состоят из двух игроков (player1 и player2).
Это вызывает довольно много проблем - например, если я выберу двух игроков (назовем их A и B ) для совместной игры, я должен проверить, существует ли уже команда, в которой Player1 - A, а Player2 - B или Player1 - B и Player2. это.
Столбцы games
и wins
присутствуют как в players
таблице, так и в teams
таблице - но это потому, что я хочу увидеть, сколько игр выиграют игроки, а также насколько совместим игрок в разных командах (как часто игрок выигрывает, когда объединяется с другой конкретный игрок).
- Рейтинговое табло (вероятно, я собираюсь использовать систему рейтинга Эло )
- Страница статистики для каждого игрока с рейтингом, победами, играми, статистикой последних игр и с какими игроками он наиболее совместим.
Я сильно подозреваю, что многое из этого нарушает некоторые принципы нормализации базы данных, и я хотел бы получить несколько советов о том, как реализовать дизайн моей базы данных.
источник
Ответы:
Есть две проблемы, которые я вижу с вашей текущей схемой, одна из них заключается в необходимости проверить два поля в таблице, чтобы определить, является ли составной ключ фактически дубликатом, и некоторые сводные данные свернуты в отдельные таблицы для отдельных сущности (особенно выигрывает, но потенциально и рейтинг игрока).
Во-первых, нет никаких хитростей в БД, чтобы заставить любое / любое поле составного ключа обрабатываться так, как вы ищете, но если ваша БД поддерживает это, вы можете создать функцию
getPlayerTeams(player_id)
для инкапсуляции запрос.(Вы также можете создать представление с team_thumbprint, рассчитанным как хэш отсортированных идентификаторов игроков, так что любая комбинация из тех же двух людей всегда приводит к одному и тому же отпечатку, но здесь это может быть немного).
Что касается нормализации, рассмотрите возможность отделения сущностей от результатов, полученных с помощью
team_result
таблицы для отслеживания всех результатов для данной группы. Немного более экстремальная нормализация также потребовала быplayer_rating_hist
таблицы, содержащей все изменения рейтинга для игрока. Их текущий рейтинг просто тот, с самой последней датой. Представление игрока также может быть использовано, чтобы содержать самые последние значения для удобства запросов.Предлагаемая схема (извините, без схемы):
Запросы:
Эта структура позволяет отделить «базовые» объекты (игроков и команды) от «контента», возникающего в результате работы системы с течением времени, и означает, что вы не постоянно обновляете одну из базовых таблиц с текущим рейтингом, # выигрышей и т. д. Это производные значения, которые следует извлекать, получая самые последние оценки, среднюю оценку
COUNT
выигрышей или проигрышей и т. д. Если система стала достаточно большой, вы можете рассмотреть возможность извлечения таких агрегированных данных в отдельный «склад» (даже если это был просто отдельный набор таблиц в одной и той же БД) для упрощения аналитики.источник