2011-03-04 79 views
1

我想制作一个简单的锦标赛系统,现在我已经来到另一面墙... 我有一个名为Teams的表 - 每个Team都可以参加多个比赛。SQL:反映锦标赛设计的设计数据库

我已经考虑过具有名为Matches表具有4列:

  • ID =>标识符
  • Team1ID =>参考ID在队
  • Team2ID =>参考团队ID
  • WinnerID =>与Team1ID或Team2ID相同的值

WinnerID然后将有一个sql触发器,检查它是否与Team1IDTeam2ID相同的值...如果不是,它将回滚事务。

这种做法似乎开始完美,直到我意识到,它打破了几个“最佳实践”的规则,包括的“每个聚合根库”,因为这需要我做:

Team myTeam1 = ... Get team1 ... 
Team myTeam2 = ... Get team2 ... 

Match myMatch = new Match { Team1 = myteam1, Team2 = myteam2; } 

这是错误的,因为Match实体被定义为Team实体的“子实体”,并且只能通过Team实体添加。

有关如何正确设计我的数据库以适应我的需求的任何建议?

+0

我不知道我是否同意该声明“比赛是团队子实体”。虽然这两者是相关的,但Matches似乎需要独立检索。我会过分考虑你的设计以满足DDD原则。 – 2011-03-04 13:46:54

+0

@John Bledsoe,好..匹配实体依赖于团队,因为它需要2个团队实体引用。 – ebb 2011-03-04 14:10:25

+0

你当然是对的,但我的意思是你可能想以除了“给我所有比赛的球队X. “在这种情况下,您将需要除团队聚合根之外的其他东西来检索匹配。 – 2011-03-04 14:56:40

回答

1

就触发器而言,我只是使用一些约束。

(Team1ID <> Team2ID) 
AND 
(WinnerID IS NULL OR Team1ID = WinnerID OR Team2ID = WinnerID) 

可能都在一个约束。至于域模型,我不会想到你通过一个团队添加一个匹配,但可能通过比赛实例:Match = Tournament.NewMatch(Team1,Team2);

可以想象,会有更高阶的赛事规则,像轮,淘汰等

因为它听起来像你的团队知道他们的世界杯上,然后创建一个团队或从数据库中检索它,它会去通过Cup:Cup.NewTeam(TeamName)或Cup.LoadTeam(TeamID)。这对于Cup.NewMatch来说仍然有意义,因为你当然不希望在不同的杯子中的球队之间进行比赛。

+0

我的错......我勉强解释 - 我的比赛更像是一个“杯子”..用户只需注册一个球队名称和其他4名球员的名字 - 球队只能在活动杯内使用,不应该使用可用于下一杯。 “Team”表有一个名为'CupID'的列,它有一个对'Cup'表的引用,这样我就可以识别哪个队在活动杯 – ebb 2011-03-04 13:52:49

+0

@ebb添加了一些注释。我仍然认为你的杯子需要一个管理实体,杯子实体本身对此很好。我经常有这样的设计 - 例如Meeting和Attendee,那里有多次会议(会议)和注册,多年来参加者可以参加不同的会议,但会议处理这种关系。 – 2011-03-04 14:35:45

+0

@Cade Roux - 我明白了..但是我的Match匹配表仍然需要引用Team Team表来验证Team1ID和Team2ID的权利吗? – ebb 2011-03-04 14:37:53

0

您的模型将如何存储平局匹配? :)

为什么不把分数存储在一个匹配行中,并根据它来确定赢家?

标识,Team1Id,Team2Id,Team1PointsScored,Team2PointsScored

+0

这场比赛不能被画出来,因为如果画画的话该怎么办。我需要的是Team1或Team2是否赢得了比赛。问题是如何为它设计表格。 – ebb 2011-03-04 14:00:07

+0

好的,那么称为IsTeam1Winner的位列怎么样? – CyberDude 2011-03-04 14:03:58

+0

我没有解释......正如我在文章中所描述的,那么我只是想知道是否让'Match'表引用'Team'表,并且在我的代码中违反了存储库每聚合原则,因为'Match'实体不会是“团队”的子实体。 – ebb 2011-03-04 14:07:40