数据库设计:: 2参与者事件中的规范化::连接表还是2列?

时间:2011-05-20 07:12:59

标签: database-design normalization

修改:更新广义问题以反映实际领域:曲棍球运动。

然后,实际的事件是游戏时间表,参与者是团队。

球队是最终的“所有者”(即当球队被删除时,任何相关的预定比赛,结果,球员和球员统计数据都会被删除。)

此线程中到目前为止讨论的问题包括决定将事件组合成具有2列(team1,team2)的单行,或者分成连接表。到目前为止的共识是:保持2列方法。但是,考虑到原始问题适用于通用事件而非预定游戏与相关结果,可能会有一个方法发生变化(例如,有些人可能会说游戏时间表应记录两个时间表信息[日期,时间,位置,球队]和比赛结果/结果信息(得分,胜负平局,点球分钟权力比赛等),因此应该添加一个联接表来生成唯一的游戏ID。)

到目前为止,回复非常好; - )将标记为已回答,等待任何更新。谢谢大家!

原始问题:


对如何解决这个问题感到困惑。

处理事件的规范化方法是什么(在给定的日期和地点进行),总共会有2个参与者?

非规范化方法是创建事件表:

1)eventID PK(autonum)
2)两列,参与者1&参与者2,来自参与者表格的PK(autonum)。

虽然这种方法确实在单个表记录中合并事件创建(没有连接表来创建eventID),但这种设计的一个问题是技术上参与者应该是方程式的拥有者;即删除参与者时,应删除任何相关事件,因为不允许孤立事件。

替代方案,一个连接表,我会看到它生成一个唯一的eventID以及日期,时间和位置。修改后的事件表将包含连接表eventID和2个单独的行,每个参与者一个。通过这种方法,我可以轻松地将FK添加到eventsID的事件表中(参与者表中的PK),从而具有适当的约束。

你会如何解决这个问题?我应该指出,我们已经在生产中使用非标准化设计几年没有问题(数据约束被推到代码级别),但我们正在寻找从地面(数据库)向上重新构建(代码),因此问题; - )


6 个答案:

答案 0 :(得分:2)

为什么你认为这不正常化?两个参与者ID都以3NF的方式依赖于事件(取决于密钥,整个密钥以及密钥,所以请帮助我,Codd)。

但是,如果日期和位置也取决于事件ID,那么它们也应放在此表中(可能该位置是外键查找另一个表,类似于参与者)。类似于:

Events:
    EventId           primary key
    Date
    LocationId        references Locations(LocationId)
    ParticipantOneId  references Participants(ParticipantId)
    ParticipantTwoId  references Participants(ParticipantId)
Locations:
    LocationId        primary key
    <<Other location stuff>>
Participants:
    ParticipantId        primary key
    <<Other participant stuff>>

仅仅因为你有一些看起来像的数组,它不会自动违反3NF,它只是一个应该被看到的警告标志。

现在,如果您发现可能有0,1,3或更多参与者的事件,那么您需要重新设计架构。

在此之前,YAGNI。

答案 1 :(得分:2)

  1. 从应用程序代码中取出约束并将它们放在它们所属的位置 - 在dbms的控制下。

  2. ID号与标准化无关。

  3. 您需要一张参与者表。设置引用ON DELETE CASCADE事件表中参与者的外键;这将使dbms在用户删除其中一个参与者时删除事件。这与数据完整性有很大关系,但与标准化无关。

答案 2 :(得分:1)

您能详细说明您提出的其他选项吗?或者这就是你所要求的?在不知道所有表格的情况下很难说,但我认为你这样做的方式很好,特别是因为它总是一对一的关系(与团队比赛)。通过你的ID(gameId,teamId等)进行索引,你会很好,不需要为了它而进行重构。

考虑一下,您真正​​获得了什么优势?

games
=========
game_id PK
game_date
game_time
location

games2teams <-- possibly overkill, since this is a 1-to-2, not 1-to-N or M-to-N
===========    
game_id
team_id

schools
==========
team_id
player_name

results
==========
game_id
team_id
score

答案 3 :(得分:1)

如果每个事件总有两个且恰好两个参与者,那么你的模式都会被标准化。

我宁愿选择不使用关系表的方法,并将在参与者1&amp;上设置FK。 Participant2字段,以确保正确的完整性。

答案 4 :(得分:1)

它看起来像一个m到n的关系(一个人可以创建/参与多个事件,一个事件可能是更多的参与者),因此你应该有3个表:

事件

  • id - PK - autoincrement
  • 其他详细信息(开始日期,持续时间,地点等)

  • id - PK - autoincrement
  • 其他详情

person_event

  • id - PK - 自动增量(这是一个替代PK,因为表中包含人和事件旁边的补充信息)
  • event_id - 有关活动的FK
  • person_id - FK on people
  • participant_role - 这可以是组织者,简单参与者,嘉宾等。

现在,您可以拥有任意数量的参与者,您可以拥有该事件的多个创建者,您可以拥有任意数量的角色,强制执行您/客户需要的任何业务逻辑

答案 5 :(得分:1)

不确定你是否想要保留游戏双方球员统计数据,但假设你这样做。还假设未定义可能的位置并且不是特别重要,因此在游戏实体中只有一个文本字段来存储它。如果您确实希望报告 按位置,则应添加位置实体,以便您可以从列表中将游戏预订到特定位置。 这是一个基本的ER模型,我认为涵盖了所有规定的规则。它应该可以帮助您获得更详细的架构。 “日记”或日志实体存储有关游戏的misc非结构化内容。例如“这是一个下雨天,一名球员在第9分钟被罚下场。等等......等等......”

enter image description here