我正在存储有关棒球统计数据的数据,并希望使用三个表来存储:players、battingStats 和 pitchingStats。出于问题的目的,每个球员都会有击球数据或投球数据,但不能同时拥有。
我将如何在 3NF 中规范这种关系?
我正在存储有关棒球统计数据的数据,并希望使用三个表来存储:players、battingStats 和 pitchingStats。出于问题的目的,每个球员都会有击球数据或投球数据,但不能同时拥有。
我将如何在 3NF 中规范这种关系?
PlayerId 将是 BattingStats 和 PitchingStats 表中的外键
[记得在统计表中加入一些时间维度(季节、年份等)]
顺便说一句,这是一个糟糕的假设:据我所知,投手也可以击球!
你真的要求不要使用超过 3 张桌子吗?归一化通常意味着将一个非归一化模型分解为许多归一化关系。
如果您可以拥有超过 3 个表,您可能需要考虑以下内容(在3NF中):
Players: ([player_id], name, date_of_birth, ...)
Batters: ([batter_id], player_id)
Pitchers: ([pitcher_id], player_id)
Batting_Stats: ([batter_id, time_dimension], stat_1, stat_2, ...)
Pitching_Stats: ([pitcher_id, time_dimension], stat_1, stat_2, ...)
中的属性[]
定义主键,但如果愿意,可以使用代理键。player_id
Batters 和 Pitches 中的属性应该有一个唯一的约束,它也应该是Players 关系的外键。Batting_Stats 和 Pitching_Stats 也应该分别具有 Batters 和 Pitching 的外键。
但请注意,上述内容并不强制规定球员只能是击球手或投手。
更新:
我知道的一种强制球员只是击球手或投手的方法是通过这个模型:
Players: ([player_id], name, date_of_birth, ...)
Roles: ([role_id, role_type], player_id)
Batting_Stats: ([role_id, role_type, time_dimension], stat_1, stat_2, ...)
Pitching_Stats: ([role_id, role_type, time_dimension], stat_1, stat_2, ...)
role_type
应该定义投手或击球手。Batting_Stats 和 Pitching_Stats 应该有一个使用(role_id, role_type)
. 对player_id
in Roles 的唯一约束将确保玩家只能拥有一个并且只有一个角色。最后添加检查约束,以便Batting_Stats.role_type = 'Batter'
和Pitching_Stats.role_type = 'Pitcher'
。这些检查约束保证 Batting_Stats 总是描述击球手,并注意投手。这同样适用于 Pitching_Stats。
我知道如何从实际的角度实现这一点(我会在不相交的表上创建一个 UNIONed 视图,并在玩家 ID 上放置一个唯一索引 - 因此,它们只能出现在一个表中)。
或者在球员表中,记录他们拥有什么类型的统计数据,然后将其包含在统计数据表中的 FK 关系中。
但其中任何一个都可能比你想要的更接近金属。