修改:更新广义问题以反映实际领域:曲棍球运动。
然后,实际的事件是游戏时间表,参与者是团队。
球队是最终的“所有者”(即当球队被删除时,任何相关的预定比赛,结果,球员和球员统计数据都会被删除。)
此线程中到目前为止讨论的问题包括决定将事件组合成具有2列(team1,team2)的单行,或者分成连接表。到目前为止的共识是:保持2列方法。但是,考虑到原始问题适用于通用事件而非预定游戏与相关结果,可能会有一个方法发生变化(例如,有些人可能会说游戏时间表应记录两个时间表信息[日期,时间,位置,球队]和比赛结果/结果信息(得分,胜负平局,点球分钟权力比赛等),因此应该添加一个联接表来生成唯一的游戏ID。)
到目前为止,回复非常好; - )将标记为已回答,等待任何更新。谢谢大家!
原始问题:
对如何解决这个问题感到困惑。
处理事件的规范化方法是什么(在给定的日期和地点进行),总共会有2个参与者?
非规范化方法是创建事件表:
1)eventID PK(autonum)
2)两列,参与者1&参与者2,来自参与者表格的PK(autonum)。
虽然这种方法确实在单个表记录中合并事件创建(没有连接表来创建eventID),但这种设计的一个问题是技术上参与者应该是方程式的拥有者;即删除参与者时,应删除任何相关事件,因为不允许孤立事件。
替代方案,一个连接表,我会看到它生成一个唯一的eventID以及日期,时间和位置。修改后的事件表将包含连接表eventID和2个单独的行,每个参与者一个。通过这种方法,我可以轻松地将FK添加到eventsID的事件表中(参与者表中的PK),从而具有适当的约束。
你会如何解决这个问题?我应该指出,我们已经在生产中使用非标准化设计几年没有问题(数据约束被推到代码级别),但我们正在寻找从地面(数据库)向上重新构建(代码),因此问题; - )
答案 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)
从应用程序代码中取出约束并将它们放在它们所属的位置 - 在dbms的控制下。
ID号与标准化无关。
您需要一张参与者表。设置引用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个表:
表事件:
表人:
表 person_event :
现在,您可以拥有任意数量的参与者,您可以拥有该事件的多个创建者,您可以拥有任意数量的角色,强制执行您/客户需要的任何业务逻辑
答案 5 :(得分:1)
不确定你是否想要保留游戏双方球员统计数据,但假设你这样做。还假设未定义可能的位置并且不是特别重要,因此在游戏实体中只有一个文本字段来存储它。如果您确实希望报告 按位置,则应添加位置实体,以便您可以从列表中将游戏预订到特定位置。 这是一个基本的ER模型,我认为涵盖了所有规定的规则。它应该可以帮助您获得更详细的架构。 “日记”或日志实体存储有关游戏的misc非结构化内容。例如“这是一个下雨天,一名球员在第9分钟被罚下场。等等......等等......”