你如何规范一对一或其他关系?

时间:2010-03-23 13:51:18

标签: normalization database-normalization 3nf third-normal-form

我正在存储有关棒球统计数据的数据,并希望通过三个表格来实现这些数据:player,battingStats和pitchingStats。出于问题的目的,每个玩家将有击球统计数据或投球统计数据,但不是两者都有。

我如何在3NF中规范化这种关系?

3 个答案:

答案 0 :(得分:6)

PlayerId将是BattingStats和PitchingStats表中的外键

[并记得在统计表中加上一些时间维度(季节,年份等)

顺便说一句,这是一个不好的假设:据我所知,投手也可以蝙蝠!

答案 1 :(得分:2)

您是否真的需要不要使用超过3个表。 Normalization通常意味着将一个非规范化模型分解为许多规范化关系。

如果您可以有超过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, ...)

[]中的属性定义主键,但如果愿意,可以使用surrogate key。击球手和球场中的player_id属性应该为unique constraint,并且它也应该是球员关系的foreign key。 Batting_Stats和Pitching_Stats也应分别拥有击球员和投球的外键。

但请注意,上述内容并未强制玩家只能是击球手或只是投手。


<强>更新

我所知道的一种方法是通过这种模式来强制玩家只是一个击球手或者只是一名投手:

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)具有Roles的复合外键。角色中player_id的唯一约束将确保玩家只能拥有一个角色,而且只能拥有一个角色。最后添加check constraints以便Batting_Stats.role_type = 'Batter'Pitching_Stats.role_type = 'Pitcher'。这些检查约束保证Batting_Stats始终描述击球手,并注意投手。这同样适用于Pitching_Stats。

答案 2 :(得分:1)

我知道如何从实际角度实现这一点(我会在不相交的表上创建一个UNIONed视图,并在玩家ID上添加一个唯一索引 - 因此,它们只能出现在一个表中)。

或者在玩家表中,记录他们拥有的统计数据类型,然后将其包含在统计数据表的FK关系中。

但其中任何一种都可能比你想要的更接近金属。