SQL数据库设计多对多

时间:2013-06-20 20:07:57

标签: sql database-design

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

播放器

id
name

匹配

id
date

PlayerMatch

player_id
match_id
home_team
goals_for
goals_against

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

6 个答案:

答案 0 :(得分:1)

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

答案 1 :(得分:1)

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

<强>播放器

id
name

<强>匹配

id
home_player_id
guest_player_id
date
goals_home_player
goals_guest_player

答案 2 :(得分:1)

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

<强>播放器

id
name

<强>匹配

id
date

<强> PlayerMatch

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*/

答案 3 :(得分: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

答案 4 :(得分:0)

这种数据关系完全不自然。要设置它,只要问自己两个问题:

  • 玩家有不止一场比赛吗?
  • 比赛有不止一个球员吗?

如果两者的答案都是肯定的,那么你就有了多对多的关系,这些并不常见。它们的实现只是稍微复杂一些。在一对多关系中,您将一个外键保存到某个表中的记录列表中。实际上,这仍然是多对多关系中的工作原理,除了Players和Matches表都需要一个外键到一些记录列表。

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

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表的外键。在“匹配”表中,您应该有两列。一个用于主队外键,一个用于客队关键。团队不是匹配的实际属性,因此为了规范化Match表,您需要将这些数据放在他们自己的表中。

答案 5 :(得分:-1)

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