SQL - проблема с нормализацией

Я создаю фэнтези-футбол, и у меня есть вопрос о том, как создать свою базу данных. Мне сложно разработать способ распределения игроков между лигами и нормализовать его.

Есть таблица со всеми возможными футболистами под названием Players, таблица, которая содержит информацию о командах под названием Teams, таблица, которая содержит информацию о пользователях под названием Users, таблица, которая содержит информацию о лиге, и таблица, в которой хранятся все другие идентификаторы таблиц, называемые Rosters.

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

У меня вопрос: как сделать игрока доступным / недоступным в базе данных, чтобы в разных лигах был одинаковый выбор игроков? Есть ли лучший способ настроить эту базу данных?

Составы

CREATE TABLE Rosters ( 
RostersID INT NOT NULL AUTO_INCREMENT ,
LeagueID INT NOT,
TeamID INT NOT NULL , 
PlayerID INT NOT NULL , 
UserID INT NOT NULL , 
PRIMARY KEY (RostersID)
)

Лиги

CREATE TABLE Leagues ( 
LeagueID INT NOT NULL AUTO_INCREMENT ,
LeagueName VARCHAR(35) NOT NULL ,  
PRIMARY KEY (LeagueID)
)

Команды

CREATE TABLE Teams (
 TeamID  INT NOT NULL AUTO_INCREMENT ,
 TeamName VARCHAR(35) NOT NULL ,
 StateCode CHAR(3) NOT NULL ,
 Ranking INT NOT NULL DEFAULT '0', 
 PRIMARY KEY (TeamID)
) 

Пользователи

CREATE TABLE Users (
 UserID  INT NOT NULL AUTO_INCREMENT ,
 UserName VARCHAR(45) NOT NULL ,
 Email VARCHAR(55) NOT NULL ,
 Password VARCHAR(45) NOT NULL ,
 PRIMARY KEY (UserID)
) 

Игроки

CREATE TABLE Players ( 
 PlayerID INT NOT NULL AUTO_INCREMENT ,
 LastName VARCHAR(50) NULL ,
 FirstName VARCHAR(50) NULL ,
 Postion VARCHAR NULL ,
 Available BOOLEAN NOT NULL DEFAULT FALSE ,
 PRIMARY KEY (PlayerID)
)

person AJ_    schedule 27.11.2016    source источник
comment
сделать игрока недоступным в базе данных, чтобы разные лиги могли выбирать одних и тех же игроков. Не считается.   -  person Strawberry    schedule 28.11.2016
comment
В разных лигах есть одинаковый выбор игроков.   -  person AJ_    schedule 28.11.2016


Ответы (4)


На самом деле это не вопрос уровня базы данных, это задача логики приложения. Что вы можете сделать на уровне базы данных, так это разместить ограничение уникальности нескольких столбцов в roster таблице на leagueid, playerid полях. Это не позволит вашему приложению дважды назначать одного и того же игрока в одну и ту же лигу. Избавьтесь от поля available.

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

select p.playerid
from players p
left join rosters r on p.playerid=r.playerid and r.leagueid=...
where r.playerid is null
person Shadow    schedule 27.11.2016

Вы можете переместить отношения между игроками и лигами в отдельную таблицу, например, с именем LeaguePlayer, и переместить туда доступный флаг. Затем измените таблицу ROSTER, чтобы она ссылалась на LeaguePlayer, а не Player.

Если вы затем ограничите базу данных так, чтобы LeaguePlayerId в таблице списка был уникальным. Затем создайте уникальное ограничение для LeaguePlayer для обоих ссылочных столбцов. Это предотвратит дублирование в лигах, в то же время позволяя различным лигам включать одного и того же игрока.

При желании вы можете удалить флаг доступности и сделать вывод, что игрок доступен по его идентификатору LeaguePlayerId, отсутствующему в таблице списка.

Пример кода ниже.

CREATE TABLE Rosters ( 
RostersID INT NOT NULL AUTO_INCREMENT ,
LeagueID INT NOT,
TeamID INT NOT NULL , 
LeaguePlayerID INT NOT NULL , 
UserID INT NOT NULL , 
UNIQUE(LeaguePlayerID),
PRIMARY KEY (RostersID)
)

CREATE TABLE LeaguePlayer (
LeaguePlayerID INT NOT NULL AUTO_INCRMENT,
LeagueId INT NOT NULL,
PlayerId INT NOT NULL,
Available BOOLEAN NOT NULL DEFAULT FALSE,
UNIQUE(LeagueId,PlayerId),
PRIMARY KEY (LeaguePlayerID)
)
person Ross G    schedule 27.11.2016
comment
Я фактически закончил тем, что сделал гибридное решение вашей diea и Shadows, где я немного разбил базы данных и избавился от таблицы Roster. Спасибо за совет. - person AJ_; 29.11.2016

С помощью своей структуры таблицы вы можете создать таблицу LeaguePlayer, которая содержит playerID и leagueID с соответствующими внешними ключами и составным первичным ключом. При объединении игроков для драфта вы вызываете запрос типа

SELECT p.playerID FROM player p LEFT JOIN LeagePlayer lp ON p.playerID
= lp.playerID WHERE lp.leagueID = current_league
person akalanka    schedule 28.11.2016

Есть отношения «1: много», а есть отношения «много: много». Вы должны решить, будет ли команда: игрок 1: много или много: много. У вас есть дизайн Roster со всеми видами возможных отношений "много: много".

Вместо этого в Player таблице должен быть столбец team_id, сигнализирующий, что это отношение 1: много (1 команда: много игроков).

Поскольку вы говорите о том, что команды выбирают игроков, вы можете указать, что игрок не был выбран, указав team_id NULL.

person Rick James    schedule 28.11.2016
comment
Итак, у команды должен быть PlayerID, и я должен удалить PlayerID из списка. Следует ли мне также удалить UserID из Roser и поместить его в команду и / или лигу? - person AJ_; 28.11.2016
comment
Также Означает ли это, что я должен исключить команду из состава и поместить TeamID в лигу, потому что в каждой лиге должна быть только 1 команда? - person AJ_; 28.11.2016
comment
Я думаю, вам нужно начать разработку схемы заново. - person Rick James; 28.11.2016