2016-11-27 65 views
1

我正在创建幻想足球游戏,我有一个关于如何设计我的数据库的问题。我很难设计一种在联赛之间分享球员的方式,并且仍然将其规范化。SQL - 规范化问题

有一张桌子,上面有所有可能的足球运动员称为球员,包含球队信息的表格称为球队,包含用户信息的表格称为用户,包含联盟信息的表格和保留所有其他表格的表格编号叫做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) 
) 
+1

查询“使玩家在数据库中不可用,使不同的联赛可以起草相同的球员。”不计算。 – Strawberry

+0

不同的联赛有相同的球员选择。 – John

回答

1

这不是一个真正的数据库级别的问题,这是一个应用程序逻辑的任务。您可以在数据库级别执行的操作是在leagueid, playerid字段的roster表中放置多列唯一约束。这会阻止你的应用程序将同一个玩家分配给同一联盟两次。摆脱available字段。

的联赛中可用的玩家可以通过在花名册表左侧的接合部球员表中列出:

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

你可以进入或许命名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) 
) 
+0

我实际上最终做了你的diea和Shadows的混合解决方案,在那里我分解了一些数据库并摆脱了Roster表。感谢您的建议。 – John

0

有“一对多”的关系,也有“多比多”的关系。你必须决定球队:球员是1:多还是多:多。你有设计Roster与各种许多:可能的关系。

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

由于您正在讨论队选队员,因此您可能想要指示玩家没有被选中,team_idNULL

+0

所以Team应该有PlayerID,我应该从名册中删除PlayerID。我是否也应该从Roser中删除UserID并将其放入团队和/或联盟? – John

+0

这是否意味着我应该把球队列入阵容并将球队ID放入联盟内,因为每个联盟只有一支球队? – John

+0

我认为你需要重新开始模式的设计。 –

1

通过您的表格结构,您可以创建一个表格LeaguePlayer,其中包含playerID和leagueID以及合适的外键和复合主键。 当草案汇集玩家你叫喜欢

SELECT p.playerID FROM player p LEFT JOIN LeagePlayer lp ON p.playerID 
= lp.playerID WHERE lp.leagueID = current_league