【问题标题】:Does this database look OK? Did I normalize properly?这个数据库看起来好吗?我正常化了吗?
【发布时间】:2012-01-29 06:51:52
【问题描述】:

我需要为我拥有的一些数据创建一个数据库,所以我尝试了一下(正如你所希望的那样),现在我需要帮助来完成最后的润色!你能帮我规范一下吗?

我用虚假数据为我在 Excel 中创建的设计拍了一张照片:

您应该知道的是,有些游戏会进行 5v5,有些会进行 3v3。我不想为 Team1P1、Team1P2、Team1P3 等添加列,而是让专家来帮助我做到这一点。

问题:根据我的文件解析器,我的应用程序将知道一个游戏是 6 人 (3v3) 还是 10 人 (5v5)。如何构建数据库以将这些玩家映射回游戏?与其尝试将Player 数据放入Games 表中,不如在Players 中添加一个指向Game ID 的列?

玩家
编号 | player_id |游戏ID |等等……

编辑澄清

Picture Starcraft 2,或任何其他在线玩的 RTS 游戏。当游戏开始时,它是一个全新的石板。一定数量的玩家加入一场比赛(3v3 或 5v5)并互相对抗。在游戏结束时,每个人都有一定的统计值(他们是赢还是输?他们有多少金币?他们有多少杀戮、死亡、助攻?)

这些统计数据中的每一个都特定于该游戏中的该玩家。

如果我那天打了 2 场比赛,我会是这样的:

标识 | player_id | stat1 | stat2 | stat3 |
1 | 100 | 500 | 600 | 700
2 | 100 | 300 | 999 | 2000

【问题讨论】:

    标签: mysql database normalization


    【解决方案1】:

    我基本同意 PeeHaa 的回答,尽管我有一些更改。首先,我同意您建议的两个表 pr0tocol 中的 id 字段令人困惑,因为您还有 game_idplayer_id 字段。就用那些吧。

    我也同意您应该有一个单独的 game_players 表,该表仅由 game_idplayer_id 组成,并且这两个字段组合起来是表的主键。

    我觉得您的stats 表的键控应该与game_players 表相同。这样,您不仅可以跟踪每个玩家的统计数据,还可以报告单个游戏的统计数据。

    编辑:

    游戏:

      key
    game_id  |  game_length  |  game_mode  |  game_type  |  ranked
    

    玩家:

       key
    player_id  |  other player data - no stats in here
    

    Game_Players

      key    |     key
    game_id  |  player_id
    

    统计数据

      key    |     key
    game_id  |  player_id  |  stat1  |  stat2  |  stat3  |  etc...
    

    使用这四个表格,您可以跟踪所有统计数据,并能够通过您选择编写的任何报告按玩家或游戏将它们分开。现在,单个玩家被分配到多少场比赛并不重要,因为它只是相关表格中键的一部分。

    【讨论】:

    • id 字段保持记录唯一。从我上面的更新中可以看出,一个玩家可以玩多个游戏,这意味着 player_id 可以重复。如果我摆脱了“id”字段,我就不再有唯一的标记。至于你们提出的统计表,id | player_id |统计类型 | statvalue,在这里不起作用。如果玩家玩了多场比赛并且每场比赛的结论都有不同的统计数据,那么这种结构是没有意义的。统计数据应附加到玩家表,因为它们是该玩家对该游戏的唯一统计值。
    • 是的,我完全理解这一点。我将更新我的答案以尝试进一步说明我在说什么,因为我认为我对自己的解释不够好。
    • 您的评论现在更有意义了。让我们聊一聊这个。由于我正在获取另一家公司的数据而不是使用我自己的数据(从日志文件解析器中读取数据),因此除了 player_id 和 stats 之外没有其他玩家数据。从理论上讲,这不会使玩家表无用吗?也许不是,但如果它所持有的只是“player_id”,我认为我不需要一个 Player 表。你都有些什么想法呢?这基本上让我做的是检查在日志文件中找到的玩家是否曾经参加过任何游戏,如果是,不要将他添加到玩家表中(已经存在)。这毫无意义
    • 我想我的意思是,对于一个特定的游戏,玩家的 PLAYER_ID 可以被认为是一个“统计”。在这种情况下,只需完全删除统计表并将“所有”玩家的统计信息(他的 ID 和 VALUES)放在“玩家”中,现在一切都变得更加简单。没有?
    • 如果你摆脱了players 表,你将失去玩家的唯一性。在您获得的日志中,甚至没有与players 表中的记录相关联的玩家姓名?您的主要问题是“我是否正确地将其正常化?”根据原始信息以及我们必须对如何输入和使用数据做出的假设,答案是否定的。希望这一切都能为您指明正确的方向!
    【解决方案2】:

    我会制作另一个表格来映射玩家和游戏。

    我还注意到你在玩家表中有统计数据。

    为玩家统计数据创建另一个表可能是更好的选择。这样,如果您以后想添加一些其他统计信息,就无需更改表格。

    桌面游戏玩家:

    game id // PK
    player id // PK
    

    表格统计:

    id
    player id
    type (e.g. stat1)
    stat
    

    【讨论】:

    • 所以创建一个 id 为 | 的 game_players 表game_id (PK) | player_id,当我将数据写入游戏和玩家列中的数据库时,是否也写入游戏玩家表?另外,我不明白统计表。能否详细介绍一下它的设计和应用?如果我在 Player 字段中添加新的统计数据,为什么会出现问题?每个统计数据都特定于特定游戏,因此玩家的旧统计数据永远不会改变。就在将来,玩家表可能会有一个额外的列(更改之前没有以前玩家的值)
    • game_players 表只是一个映射。该表有 2 个foreign keys(gameid 和 playerid),primary key 将是 gameid 和 playerid 的组合。
    • @pr0tocol 关于:Each stat is specific to a particular game。为什么你的玩家表中有它比?您能否将您的问题扩展到确切的规则是什么?
    • 我在接近尾声时编辑了我的原始帖子,以供您查看。我希望这使它更清楚:)。您应该注意到这些都是 30-60 分钟的短游戏,同一个人 (player_id) 可以玩多场比赛,并在每场比赛结束时获得不同的统计数据。我认为我原来的 Players 表模式是合适的,而您的建议只是出于您的困惑。是吗?
    【解决方案3】:
    Game
    ----
    GameId
    Length
    Mode
    Type
    Ranked
    PRIMARY KEY (GameId)
    
    Team
    ----
    TeamId
    TeamName (only if you need it)
    ... other stuff about team
    PRIMARY KEY (TeamId)
    
    Player
    ------
    PlayerId
    PlayerName
    ... other stuff about player
    PRIMARY KEY (PlayerId)
    

    以及哪个球员参加哪个球队:

    TeamPlayer
    ----------
    TeamId
    PlayerId
    PRIMARY KEY (TeamId, PlayerId)
    FOREIGN KEY (TeamId)
      REFERENCES Team(TeamId)
    FOREIGN KEY (PlayerId)
      REFERENCES Player(PlayerId)
    

    以及哪些球队参加了哪些比赛:

    GameTeam
    --------
    GameId
    TeamId
    PRIMARY KEY (GameId, TeamId)
    FOREIGN KEY (GameId)
      REFERENCES Game(GameId)
    FOREIGN KEY (TeamId)
      REFERENCES Team(TeamId)
    

    和统计数据:

    GamePlayerStatistics
    --------
    GameId
    TeamId
    PlayerId
    ... statistics columns per player per game
    PRIMARY KEY (GameId, PlayerId)
    FOREIGN KEY (GameId, TeamId)
      REFERENCES GameTeam(GameId, TeamId)
    FOREIGN KEY (TeamId, PlayerId)
      REFERENCES TeamPlayer(TeamId, PlayerId)
    

    如果您的所有游戏都恰好有 2 个团队,则可以删除 GameTeam 表。然后,您需要 Game 中的两列,例如 Team1IdTeam2Id 作为 Team 的外键,并对 Statistics 表进行一些修改。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-02-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-05-08
      • 1970-01-01
      相关资源
      最近更新 更多