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_id
为 NULL
来表明球员还没有被挑选。
使用您的 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
我正在制作梦幻足球游戏,我对如何设计我的数据库有疑问。我很难设计一种在联盟之间共享球员的方式,但仍要将其标准化。
有一个 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_id
为 NULL
来表明球员还没有被挑选。
使用您的 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