我想建模一个数据库来存储几种类型的比赛数据(不同类型的模式:单轮,双轮,联赛,联赛季后赛,输家……).

也许,这个项目将成为一种商标:www.challonge.com

我的问题是:如何在sql-relationship数据库中创建一个模型来存储所有这类锦标赛?

我无法想象如何做这项工作.有很多不同的表,但所有表都与一个属性相关:tournamentType …

我可以存储tournamentType字段并使用此字段在查询中选择适当的表吗?

谢谢

解决方法:

我可以理解为什么你在为这个建模而苦苦挣扎.这很困难的一个关键原因是因为object relational impendance-mismatch.虽然我是SQL的忠实粉丝,但它是一种非常强大的组织数据的方式,它的一个缺点 – 以及NoSQL存在的原因 – 是因为SQL与面向对象编程不同.当您描述具有不同匹配的联赛时,很容易以对象形式对其进行描绘:Match对象由League_Match,Round_Match,Knockout_Match等扩展.每个Match对象包含两个Team对象.团队可以扩展到赢家和失败者……

但这不是SQL数据库的工作方式.

所以让我们将其转化为关系:

I want to model a database to store data of several types of tournaments (whith different types of modes: single rounds, double rounds, league, league + playoffs, losers, …).

>锦标赛和“模式”是一对多(1:n)的关系.

>每场比赛都有很多球队,每支球队都可以参加很多比赛(n:n).

>每支球队都有很多比赛,每场比赛有两支球队(n:n).

>每场比赛都有多场比赛,但每场比赛只属于一场比赛(1:n).

这里缺少的部分难以定义为普遍关系?

– 在轮次中,每场未来的比赛都有两支球队.

– 在淘汰赛中,根据初始球队的数量,每场未来的比赛都有指数但不断缩小的选择.

您可以在数据库层中定义它,也可以在应用程序层中定义它.如果您的目标是保持参照完整性(这是我使用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
]

正如我所看到的,除了淘汰赛之外,这种方法效果很好,在那里你实际上并不知道哪支球队会在淘汰赛之前与其他球队比赛.这证实了我的感觉,即我们将创建一个锦标赛级别的后代来处理特定类型的锦标赛.

因此,我建议使用以下列的三个表:

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)

您已在此模型中使用了子表.这样做的好处是淘汰赛和圆/联赛非常不同,你对他们的看法不同.缺点是你要增加额外的复杂性,你将不得不处理.这可能有点烦人,但根据我的经验,试图避免它只会增加更多的麻烦,并使其可扩展性低得多.

现在我将回到参照完整性.这种设置的挑战是理论上,当它们只属于一个时,你可以在Match_Round和Match_Knockout中都有值.为了防止这种情况,我会使用TRIGGER.基本上,在Match_Round和Match_Knockout表上都有一个触发器,如果tournament_type不可接受,则会阻止INSERT.

尽管设置起来有点麻烦,但它确实具有易于转换为对象同时仍保持参照完整性的快乐好处.

标签:sql,mysql,database-design