SQL - 规范化问题

SQL - Normalization Trouble

我正在制作梦幻足球游戏,我对如何设计我的数据库有疑问。我很难设计一种在联盟之间共享球员的方式,但仍要将其标准化。

有一个 table 包含所有可能的足球运动员,称为 Players,一个包含球队信息的 table 称为 Teams,一个 table 包含称为 Users 的用户信息,一个 table 包含联赛信息和一个 table 保存所有其他 table 的 id's id's called Rosters。

基本上有一个联盟有一定数量的球员,一旦选秀开始,球员就会被安排到一个球队,如果他们属于一个球队,他们就不能再被选拔。我遇到的问题是,与多个联赛分享这些球员。目前我有一个布尔值设置给玩家,如果他们可用或不可用。这一直有效,直到另一个联盟尝试征召该球员,因为他们已被设置为不可用。

我的问题是我应该如何在数据库中制作球员 available/unavailable 以便不同的联赛有相同的球员选择?有没有更好的方法来设置这个数据库?

花名册

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)
)

您可以将球员和联赛之间的关系移到一个单独的 table 中,也许名为 LeaguePlayer 并将可用标志移到那里。然后修改 ROSTER table 以引用 LeaguePlayer 而不是 Player。

如果您随后约束数据库,使名册上的 LeaguePlayerId table 是唯一的。然后为两个引用列在 LeaguePlayer 上创建唯一约束。这将防止联赛中的重复,同时允许不同的联赛包括同一名球员。

您可以选择删除可用标志,并根据未出现在名单中的 LeaguePlayerId 推断球员可用 table。

示例代码如下。

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)
)

这实际上不是数据库级别的问题,这是应用程序逻辑的任务。您可以在数据库级别上做的是在 leagueid, playerid 字段的 roster table 中放置一个多列唯一约束。这将防止您的应用程序将同一名球员分配到同一联赛两次。删除 available 字段。

一个联盟的可用球员可以通过左加入名单上的球员 table 来列出 table:

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

有“1:many”个关系,还有"many:many"个关系。您必须决定 team:player 是 1:many 还是 many:many。您的设计 Roster 具有各种可能的 many:many 关系。

相反,Player table 应该有一个列 team_id,从而表示它是一个 1:many 关系(1 个团队:许多玩家)。

既然你在谈论球队挑选球员,你可能想通过让 team_idNULL 来表明球员还没有被挑选。

使用您的 table 结构,您可以创建一个 table LeaguePlayer,其中包含具有适当外键和复合主键的 playerID 和 leagueID。 当汇集球员参加选秀时,您会调用

之类的查询
SELECT p.playerID FROM player p LEFT JOIN LeagePlayer lp ON p.playerID
= lp.playerID WHERE lp.leagueID = current_league