Mou*_*Mou 4 mysql sql database-design
我想建立一个数据库来存储几种类型的锦标赛数据(不同类型的模式:单轮,双轮,联赛,联赛+季后赛,输家......).
也许,这个项目将成为一种商标:www.challonge.com
我的问题是:如何在sql-relationship数据库中创建一个模型来存储所有这类锦标赛?
我无法想象如何做这项工作.有很多不同的表,但所有表都与一个属性相关:tournamentType ...
我可以存储tournamentType字段并使用该字段选择上查询此时,相应的表?
谢谢
我可以理解为什么你在为这个建模而苦苦挣扎.这很困难的一个关键原因是因为对象关系阻碍不匹配.虽然我是SQL的忠实粉丝,但它是一种非常强大的能够组织数据的方式,它的一个缺点 - 以及NoSQL存在的原因 - 是因为SQL与面向对象编程不同.当你描述的联赛,不同的比赛,这是很容易在对象的形式拍下这一刻:一个Match目的是通过扩展League_Match,Round_Match,Knockout_Match,等等.每个这样的Match对象包含两个Team对象.Team可扩展到Winner和Loser...
但这不是SQL数据库的工作方式.
所以让我们将其转化为关系:
我想建立一个数据库来存储几种类型的锦标赛数据(不同类型的模式:单轮,双轮,联赛,联赛+季后赛,输家......).
这里缺少的部分难以定义为普遍关系? - 在轮次中,每场未来的比赛都有两支球队. - 在淘汰赛中,根据初始球队的数量,每场未来的比赛都有指数但不断缩小的选择.
您可以在数据库层中定义它,也可以在应用程序层中定义它.如果您的目标是记住参照完整性(这是我使用SQL数据库的关键原因之一),那么您将希望将其保留在数据库中.
另一种看待这种情况的方法:我发现,当我考虑最终结果时,通过将其视为可以与之交互的JSON(或数组,如果您愿意),我最容易设计数据库.
我们来看一些示例对象:
比赛:
[
{
name: "team A",
schedule: [
{
date: "11/1/15",
vs: "team B",
score1: 2,
score2: 4
},
{
date: "11/15/15",
vs: "team C",
}
]
}
],
[
//more teams
]
Run Code Online (Sandbox Code Playgroud)
正如我所看到的,除了淘汰赛之外,这种方法效果很好,在那里你实际上并不知道哪支球队会在淘汰赛之前与其他球队比赛.这证实了我的感觉,即我们将创建一个Tournament类的后代来处理特定类型的锦标赛.
因此,我建议使用以下列的三个表:
Tournament
- id (int, PK)
- tournament_name
- tournament_type
Team
- id (int, PK)
- team_name (varchar, not null)
# Any other team columns you want.
Match
- id (int, PK, autoincrement)
- date (int)
- team_a_score (int, null)
- team_b_score (int, null)
- status (either future, past, or live)
- tournament_id (int, Foreign Key)
Match_Round
- match_id (int, not null, foreign key to match.id)
- team_a_id (int, not null, foreign key to team.id)
- team_b_id (int, not null, foreign key to team.id)
Match_Knockout
- match_id (int, not null, foreign key to match.id)
- winner__a_of (match_id, not null, foreign key to match.id)
- winner_b_of (match_id, not null, foreign key to match.id)
Run Code Online (Sandbox Code Playgroud)
您已在此模型中使用了子表.这样做的好处是淘汰赛和圆/联赛非常不同,你对他们的看法不同.缺点是你要增加额外的复杂性,你将不得不处理.这可能有点烦人,但根据我的经验,试图避免它只会增加更多的麻烦,并使其可扩展性降低.
现在我将回到参照完整性.这种设置的挑战在于理论上你可以在两者中都有值Match_Round,Match_Knockout当它们只属于一个时.为了防止这种情况,我会利用TRIGGERs.基本上,在Match_Round和Match_Knockout表上都有一个触发器,这可以防止INSERT如果tournament_type不接受.
尽管设置起来有点麻烦,但它确实具有易于转换为对象同时仍保持参照完整性的快乐好处.