0

我正在创建一个基于体育游戏的数据库来存储比赛和每场比赛中涉及的每个球员。我在解决多对多关系时遇到了麻烦。我目前有以下表格:

播放器

id
name

匹配

id
date

玩家匹配

player_id
match_id
home_team
goals_for
goals_against

一场比赛总是至少有两名球员。这是这种方法的最佳设计吗?

4

6 回答 6

1

这是一个有效的选项,尽管我建议您在两个表中使用相同的列名的命名约定(即在 Match 和 PlayerMatch 中使用 match_id;对于 player_id 相同)。这有助于使您的 SQL 更加清晰,并且在某些数据库 (MySQL) 中进行连接时,您可以使用 'using (col1, col2, ...)' 语法进行连接。

于 2013-06-20T20:15:30.070 回答
1

我不会使用多对多关系,我会这样做:

播放器

id
name

匹配

id
home_player_id
guest_player_id
date
goals_home_player
goals_guest_player
于 2013-06-20T20:19:00.453 回答
1

我建议坚持多对多关系。这使您可以轻松更改游戏中可以拥有多少玩家的规范,同时不会使数据模型过于复杂。

播放器

id
name

匹配

id
date

玩家匹配

player_id
match_id
is_home
goals_for
goals_against

外键从PlayerMatchPlayer
外键从PlayerMatchMatch

    --All the matches a player has played in.
    SELECT m.* 
    FROM Player p
    JOIN PlayerMatch pm
        ON p.id = pm.player_id
    JOIN Match m
        ON m.id = pm.match_id
    WHERE p.id = /*your player Id*/

    --All the players in a match
    SELECT p.*
    FROM Match m
    JOIN PlayerMatch pm
        ON m.id = pm.match_id
    JOIN Player p
        ON p.id = pm.player_id
    WHERE m.id = /*your match Id*/

    --player information for a single match.
    SELECT pm.*
    FROM Player p
    JOIN PlayerMatch pm
        ON p.id = pm.player_id
    JOIN Match m
        ON m.id = pm.match_id
    WHERE p.id = /*your player Id*/
        AND m.id = /*your match Id*/
于 2013-06-20T20:25:14.570 回答
0

我想我会先尝试为比赛建模,然后看看表格设计会发生什么:

Match
-------------
match_Id
player1_Id
player2_Id
player1_Goals
player2_Goals

其中 player1_Id 和 Player2_Id 都是 Player 表的外键

Player
---------
Id
Name

按照惯例,player1 永远是主队

那么你会像这样查询它

Select p1.name as player1_Home, p2.name as player2_away, 
matchId, 
player1_Goals as homeGoals, player2_Goals as awayGoals           
from Match m 
inner join Player p1 on p1.id = m.Player1_Id 
inner join Player p2 on p2.id = m.Player2_Id
于 2013-06-20T20:28:44.543 回答
0

这种数据关系并非不自然。要进行设置,只需问自己两个问题:

  • 球员有不止一场比赛吗?
  • 比赛是否有不止一名球员?

如果两者的答案都是肯定的,那么你有一个多对多的关系,这些并不少见。它们的实现只是稍微复杂一些。在一对多关系中,您将持有某个表中记录列表的外键。碰巧,这仍然是它在多对多关系中的工作方式,除了 Players 和 Matches 表都需要某个记录列表的外键。

此列表称为桥接表。因此,您总共需要使用三个表来描述关系

Players
-------
player_id
<player attribute columns, eg last_name, first_name, goals_scored, etc.>

Player_Match
------------
player_id
match_id


Matches
-------
match_id
<a list of columns that are match attributes, eg. match date, etc.>

上图中间的表格称为桥牌表,它只是将玩家映射到比赛,还将比赛映射到球员列表。通常,桥接表只有 2 列,每列代表一个桥接表的外键。桥接表中不需要主键,如果没有主键,则意味着玩家可以拥有多个相同的匹配项。如果玩家只能拥有一种匹配项,则将桥接表每一行的主键作为两列上的复合键。

在数据库设计中,规范化是一个非常理想的关系目标,因为它为数据库提供了最大可能的灵活性和最低的冗余量。为了规范化,问问自己你想放入表中的数据是否——真的——主键描述的对象的实际属性。例如, home_team 是否是比赛的实际属性。我会说不,不是。在这种情况下,您应该将 PlayerMatch 表中的 home_team 替换为 Teams 表的外键。在您的 Matches 表中,您应该有两列。一个用于主队外键,一个用于客队键。球队不是比赛的实际属性,因此要标准化 Match 表,您需要将这些数据放在他们自己的表中。

于 2013-06-20T21:19:52.347 回答
-1

同意 M Hagopian,op 模式看起来是一个好的开始。

于 2013-06-20T20:27:28.257 回答