代表NCAA男子篮球支架的最佳数据库架构是什么?如果您不熟悉,可以使用以下链接:http://www.cbssports.com/collegebasketball/mayhem/brackets/viewable_men
我可以看到几种不同的方法来建模这些数据,包括单个表,许多表,硬编码列,某种动态方式等。您需要一种方法来模拟每个团队所处的种子和位置,以及每个游戏以及每个游戏的结果(以及可能得分)。你还需要一种方法来代表谁在锦标赛的哪个阶段比赛。
本着疯狂三月的精神,我认为这是一个很好的问题。这里有一些明显的答案,这个问题的主要目标是看到你能够回答它的所有不同方法。哪种方式最好可能对您正在使用的语言具有主观性,或者您使用它的确切程度如何,但尝试保持答案与数据库无关,语言无关且相当高级别。如果有人对更好的方式提出任何建议,或者更好的方式来定义它,请在评论中告诉我。
答案 0 :(得分:10)
自然倾向是按照比赛顺序查看括号。你从外面阅读传统的图表。但是让我们反过来想一想。每场比赛都在两队之间进行。一个赢了,另一个输了。
现在,除此之外还有更多内容。一对特定游戏的获胜者在另一场比赛中相互对峙。因此,无论谁在这些游戏中玩游戏,游戏本身之间也存在关系。也就是说,在每场比赛中面对的球队(第一轮除外)是两场早期比赛的获胜者。
所以你可能会注意到每个游戏都有两个“儿童游戏”在它之前,并确定谁在该游戏中面对。这听起来就像二叉树:每个根节点最多有两个子节点。如果你知道谁赢了每场比赛,你可以轻松地确定“父”比赛中的球队。
因此,要设计一个数据库来对其进行建模,您实际上只需要两个实体:Team
和Game
。每个Game
都有两个与其他Game
相关的外键。名称并不重要,但我们会将它们建模为单独的键,以强制要求每个游戏不超过两个前面的游戏。我们称它们为leftGame
和rightGame
,以保持二叉树的命名。同样,我们应该有一个名为parentGame
的密钥来跟踪反向关系。
另外,正如我之前提到的,你可以通过查看赢得前两场比赛的人来轻松确定每场比赛中面对的球队。所以你真的只需跟踪每场比赛的胜利者。因此,为Game
实体提供一个winner
外键到Team
表。
现在,播种支架的问题很小。也就是说,为第一轮比赛的比赛建模。您可以通过在整个竞赛中为每个团队Game
建立一个winner
,其中该团队为Game:
winner: Team
leftGame: Game
rightGame: Game
parentGame: Game
other attributes as you see fit
Team:
name
other attributes as you see fit
且之前没有游戏。
因此,整体架构将是:
{{1}}
当然,你会将你想要的所有其他信息添加到实体中:位置,分数,结果(如果游戏是通过没收或其他一些不同寻常的条件赢得的话)。
答案 1 :(得分:5)
对于RDBMS,我认为仍然足够灵活以适应大多数情况的最简单方法是执行以下操作:
团队有 [team-id(PK)] , [name] , [region-id( FK到区域)] , [initial-seed] 。每个团队您将有一个条目。 (区域表是一个简单的代码表,只有四个条目,每个NCAA区域一个,这里没有列出。)
参与者有 [游戏ID(FK到游戏)] , [team-id(FK to 团队)] , [得分(可空)] , [结果] 。 [得分] 可以为空,以反映团队可能会丧失资金。每场比赛通常会有两名参赛者。
游戏有 [游戏ID(PK)] , [日期] , [位置] 。要了解哪些球队参加了比赛,请在参与者表格中查找相应的游戏ID。 (请记住,如果有人退学或被取消资格,可能会有两个以上的球队。)
要设置初始括号,请将相应的种子相互匹配。在玩游戏时,请注意哪个团队为特定游戏拥有 outcome = Winner ;这支球队与另一场比赛的胜利者相匹配。填写括号,直到没有更多的获胜队伍离开。
答案 2 :(得分:2)
由于你没有指定RDBMS,因为我本周末正在阅读这篇文章,所以我会采用CouchDB方法。这是我提出的代表游戏的文档结构。
{
"round" : 1, //The final would be round 5, and I guess Alabama St. vs. Morehead would be 0
"location" : "Dayton, OH",
"division": "South",
"teams" : ["UNC", "Radford"] //A feature of Couch is that fields like teams don't need a fixed nuber of columns.
"winner" : "UNC" //Showing my bias
}
更有趣或更完整的应用程序可能还有用于存储在某处的团队,排名等数据。看起来John的方法很好地涵盖了这个角度。我欢迎那些对我的沙发技能有更好了解的人的评论。
答案 3 :(得分:2)
我创建了一个包含以下表格的小型系统:
游戏:GameId,TournId,RoundId,序列,日期,VisitorId,VisitorScore,HomeId,HomeScore,WinnerId,WinnerGameId,WinnerHome(位)
预测:PredId,UserId,GameId,PredVisitorId,PredHomeId,PredWinnerId
轮次:RoundId,TournId,RoundNum,Heading1,Heading2
团队:TeamId,TournId,TeamName,Seed,MoreInfo,Url
锦标赛:TournId,TournDesc
用户:TournId,UserName
WinnerGameId将游戏的获胜者与下一场比赛联系起来。 WinnerHome告诉胜利者是下一场比赛的主场还是观众。除此之外,我认为这是非常自我解释的。
答案 4 :(得分:1)
4个表:
团队(团队,地区,种子)
用户(UserId,电子邮件,blablabla)
括号(BracketId,UserId,Points)
选择(BracketId,GameId,Team,Points)
一个人提交的每个括号在Pick表中将有63行 在每场比赛结束后,您将更新选秀表以对个人选秀进行评分。对于尚未播放的游戏,此表中的积分字段将为空,对于错误的选择,该值将为0,对于正确的选择,该积分将为正数。 GameId只是一个关键,用于识别此选择的用户支架位置(例如:East_Round2_Game2,FinalFour_Game1)。
每次更新选择表后,可以更新括号表中的points列,使其包含该括号的点总和。最看重的事情将是积分榜,每次有人想要查看排行榜时都不想再重新计算。
您不需要保留一张桌面,其中包含实际播放的所有游戏或其结果,只需在每场比赛后更新选择表。您甚至可以通过查看选择表中的“点”列来突出显示正确/不正确的选择。
答案 5 :(得分:1)
Proposed ER Diagram http://img257.imageshack.us/img257/1464/ncaaer.jpg
我们需要了解一个团队的名字和种子。因此,我们需要一个“团队”表来存储种子值。唯一的候选键是团队名称,因此我们将使用它作为主要来保持简单。 NCAA球队的名字不太可能在单场锦标赛期间发生变化,或者包含重复项,因此它应该是一个足够的关键。
“MatchUp”表可用于将球队配对到每场比赛中。 “团队”的外键(FK1,FK2)将确保团队存在,并且这些值的主键确保团队只相互匹配一次。
“MatchUp”表中“Team”表的外键(FK4)将记录获胜者。从逻辑上讲,获胜者需要成为参加比赛的两支球队之一。对主键的检查约束可以确保这一点。
一旦确定了比赛的结果,就可以从球队桌上检索维克多的种子,以便与其他维克多比较,以确定随后的比赛。在这样做的情况下,可以将FK(FK3)发送到确定的比赛,以便描述比赛的进度(尽管这些数据可能随时得出)。
我还模拟了每场比赛的比赛。游戏通过匹配来识别,它是匹配过程中发生的顺序的一部分和序列号。游戏中有一个来自团队表(FK2)的赢家。分数也可以记录在此表中。
答案 6 :(得分:1)
跟踪大量不同的支架预测:您可以使用67位来跟踪每个游戏的结果。 (即,在锦标赛中参加的六十七场比赛中的每场比赛均由一位代表,1 =“队伍A获胜”,0 =“队伍B获胜”)。要显示任何给定的括号,您可以使用一个非常简单的函数将67位映射到UI。该函数知道团队名称及其初始位置,然后在跟踪“位板”时跟踪它们在括号中的移动。
答案 7 :(得分:-4)
我对所有数据库都使用相同的模式。
t
--------
1 guid PK
2 guid FK
3 bit
然后在我的代码中:
select [2],[3] from t where [1] = @1
@ 1是我提取的数据的ID。然后如果[2]不为空,我再次选择,将@ 1设置为[2]。
这样可以很容易地模拟您发布的情况。