数据库设计:订单重要的多对一设计

时间:2016-10-07 06:31:29

标签: sql sql-server relational-database

我有两个表,用户游戏游戏包含sideRed列和sideBlue列。每一方只有一个用户。 用户有列activeGame。如果sideRedsideBlue是一对一关系,那么后方引用activeGame会去哪里?

1 个答案:

答案 0 :(得分:2)

有很多用户和很多游戏。用户应以某种方式连接到游戏。这是典型的 m:n-relationship

在您的情况下,这是受限制的:每个游戏只有一个用户为sideRed,一个用户为sideBlue。目前,您的game表有两个FK列到user - 表引用蓝色和红色用户。到目前为止正确吗?

问自己一些问题:

  • 游戏可以连接到这两个以上的用户(可能稍后)吗?
  • 用户可以连接多个游戏(可能是因为您正在寻找标记活动游戏的地方)
  • 是否允许用户主动(可能稍后)玩多个游戏(相同类型)?
  • 如果您有多个不同的游戏:用户可以同时参加多个不同的游戏吗?如果是:是否有几个不同的游戏,你需要不止一个activeGame旗帜?

你应该始终考虑你的想法: - )

您可以将fk-column放入user - 表中以引用活动游戏。问题:您的用户必须存在以填充游戏行的红色和蓝色列,但游戏必须存在以填充用户的activeGame列。这个交叉引用需要特别努力插入...

您可以在BITsideRed之外设置两个sideBlue列,以将此引用标记为activeReference。在这种情况下,您必须确保每个用户不允许多个活动标志。

我的建议(见更新部分!)

之间放置一个映射表
  • 桌面游戏(只是描述游戏的元数据,没有实例数据)
  • 表用户(只是描述用户的元数据,没有实例数据)
  • 表UserGame(UserID,GameID,TypeID [红色,蓝色,......] ......)
  • table Session(主动玩游戏:UserGameID,loginTime,...)

一位聪明人说:一个好的数据库将在其表的计数上重新认识。越多越好: - )

嗯,越多越好可能不是一般规则,但是 - 在大多数情况下 - 人们不应该害怕在一个良好和可扩展的结构中投入更多的东西

更新

您的评论

  

我喜欢这种解决方案,因为它有很强的关注点。   让我们说Shnugo采取了行动,我们必须向所有用户广播。   Shnugo的客户端发送UserGameID和请求的移动。那你就是   1.查询UserGame匹配UserGameID。 2.查询游戏匹配GameID并应用移动。 3.查询匹配GameID的UserGames并关注   联接以获取游戏中的用户ID列表。这是对的吗?

我设计中的游戏桌只是游戏本身的元描述(名称,图标,一些规则......)。特定游戏的状态(例如,所有国际象棋棋子的当前位置)将需要一个(或几个)更多的桌子,而UserGame - 表应该包含对此的参考GameStatus - 表格而不是GameID )。您可能需要几个不同的表,因为国际象棋的状态需要其他结构而不是扑克的状态。但是 - 调查UserGame会告诉你哪个游戏正在播放,所以你知道要查看哪个表。

新建议

  • table Game(只是描述游戏的元数据,没有实例数据)
  • 表用户(仅描述用户的元数据,无实例数据)
  • 表GameInstance(当前玩游戏的状态,GameID,StatusID,......)

    • 游戏特定表格,用于存储游戏的当前状态
  • 表UserGame(UserID, GameInstanceID ,TypeID [红色,蓝色,......] ......)

  • table Session(主动玩游戏:UserGameID,loginTime,...)

另一种可能性是存储所有移动并计算当前状态。但这对任何类型的游戏都不起作用。