如何将几个锦标赛/括号类型建模到SQL数据库中?

Mou*_*Mou 4 mysql sql database-design

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

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

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

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

我可以存储tournamentType字段并使用该字段选择上查询此时,相应的表?

谢谢

smc*_*nes 7

我可以理解为什么你在为这个建模而苦苦挣扎.这很困难的一个关键原因是因为对象关系阻碍不匹配.虽然我是SQL的忠实粉丝,但它是一种非常强大的能够组织数据的方式,它的一个缺点 - 以及NoSQL存在的原因 - 是因为SQL与面向对象编程不同.当你描述的联赛,不同的比赛,这是很容易在对象的形式拍下这一刻:一个Match目的是通过扩展League_Match,Round_Match,Knockout_Match,等等.每个这样的Match对象包含两个Team对象.Team可扩展到WinnerLoser...

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

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

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

  • 锦标赛和"模式"是一对多(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
]
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_RoundMatch_Knockout表上都有一个触发器,这可以防止INSERT如果tournament_type不接受.

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