【问题标题】:How do I normalise this database design?我如何规范这个数据库设计?
【发布时间】:2010-11-18 08:55:38
【问题描述】:

我正在为客户创建一个划船报告和统计系统,目前我的结构类似于以下内容:

-----------------------------------------------------------------------------
| ID | Team     | Coaches    | Rowers     | Event     | Position | Time     |
-----------------------------------------------------------------------------
| 18 | TeamName | CoachName1 | RowerName1 | EventName | 1        | 01:32:34 |
|    |          | CoachName2 | RowerName2 |           |          |          |
|    |          |            | RowerName3 |           |          |          |
|    |          |            | RowerName4 |           |          |          |
-----------------------------------------------------------------------------

这是一个示例数据行,但我想将其扩展到 Rowers 表和 Coaches 表等,但我不知道如何最好地将其链接回 Entries 表,这就是.

有没有人有什么智慧之言可以和我分享?

更新

一个团队可以有任意数量的教练和赛艇运动员,一个赛艇运动员可以在多个团队中(团队 A、B、C 等),一个团队可以有多个教练。

【问题讨论】:

  • 有没有多对多的关系?

标签: database-design normalization database-agnostic


【解决方案1】:

我会为团队、教练、赛艇运动员(如果您想要扩展的运动类型不止一种,可能是运动员)和赛事设置单独的表格。

团队

团队ID

教练

教练ID

赛艇运动员

赛艇编号

活动

事件ID 团队ID 划手ID

还有很多其他问题可以进一步定义关系,例如:什么定义了条目(事件)?是一组赛艇运动员和一名教练的 PER 比赛吗?每个赛事每组赛艇运动员有多位教练?有团队吗?团队由什么组成?

我会问这样的问题...

【讨论】:

  • 我已经做到了这一点,但是我如何使用现有的方法记录多个赛艇运动员和教练对抗团队和/或赛事的情况?
  • 请参阅我的 cmets 到我的原始帖子,其中更详细地解释它。
  • 您必须在这些多对多关系之间定义一个对应的表。如果您可以让多个团队参加多个赛事,那么在这两个中间会有一个名为 TeamEvents 的表格,其中包含两者的键(TeamID、RowerID).. 你关注了吗?
  • 请你提供一个例子,我想我不明白你的意思吗?
  • 如果您知道您将拥有多对多关系,您应该使用“介于”它们之间的表格来处理它,将它们解析为更简单的多对一和一多对多关系。如果是这种情况,那么我的第一个示例对您不起作用,因为它并不那么简单。因此,您需要扩展设计以处理复杂性。
【解决方案2】:

您说您发布的是“条目表”,但此表没有多大意义,至少就(一行,没有双关语)=(一个事实或事物)而言。

您的表中有一行是 (NULL,NULL,NULL,RowerName3,NULL,NULL,NULL)。那是什么意思? CoachName2 的教练是干什么用的?以此类推。

或者这可能是您的 Entries 表的“一行”?如果是这样,它就不是一个好的 SQL 表,因为您在单个行列交集中有行者列表(例如),而“行者列表”不是数据类型的好选择。

如果只看一些数据,就不可能说如何规范化数据库。您需要了解数据在它所建模的业务中的含义和代表。

也就是说,在我看来,您至少需要单独的表格

团队 教练员 赛艇运动员 活动

然后您需要表示业务场景的各个方面,例如“一名赛艇运动员只属于一个团队”、“一个团队至少有一名教练,并且没有教练教练超过一个团队。”

我不知道条目是什么,但也许您也需要一个条目表。也许如果我知道划船会更有意义。

【讨论】:

  • 我在数据中添加了更多上下文,这有帮助吗?这是我被赋予使用的 Access 数据库。当结构更好地标准化时,我打算将它放在 SQL Server 上。我同意你的看法,这不是我见过的最好的。
【解决方案3】:

我会有以下表格:

团队:ID、团队名称 教练:ID、CoachName、TeamID 划船者:ID、划船者名称、团队 ID

然后您的事件表将填充如下:

事件:ID、TeamID、CoachID、RowerID、EventName、位置、时间

如果您想在查询中显示非规范化数据,您可以构建如下内容:

SELECT E.ID, T.TeamName, C.CoachName, R.RowerName, E.EventName, E.Position, E.Time
FROM Event E
INNER JOIN Team T
ON E.TeamID = T.ID
INNER JOIN Coach C
ON E.CoachID = C.ID
INNER JOIN Rower R
ON E.RowerID = R.ID

【讨论】:

    【解决方案4】:

    一种链接表?然后我如何将多个赛艇运动员和教练映射到一个团队?

    这是我的提议(基于Optimal Solutions' answer):

    团队
    团队ID
    团队名称

    教练
    教练ID
    教练姓名

    赛艇
    赛艇运动员ID
    赛艇运动员姓名

    活动
    事件ID
    职位
    时间

    1. 如果您想要预定义的团队:

    CoachTeamLinkCoachsTeams 之间的链接)
    团队ID
    教练ID

    RowerTeamLinkRowersTeams 之间的链接)
    团队ID
    赛艇编号

    EventTeamLinkEventsTeams 之间的链接)
    团队ID
    事件ID

    1. 或者如果你不这样做:

    EventCoachLinkEventsCoachs 之间的链接)
    事件ID
    教练ID

    EventRowerLinkEventsRowers 之间的链接)
    事件ID
    赛艇编号

    【讨论】:

    • 感谢 Leonel 你解释得很好。
    【解决方案5】:

    我会尝试这样的事情::

    团队 ID 姓名 赛艇运动员 ID 姓名 team_id 参考团队 (id) 教练员 ID 姓名 team_id REFERENCES 团队 (id) 事件 ID 姓名 起始时间 长度 event_teams event_id 引用事件 (id) team_id 引用团队 (id) 位置

    【讨论】: