使用0 / NULL值进行标准化还是可以设计得更好?

时间:2017-01-09 10:51:38

标签: mysql sql-server database-design normalization database-normalization

我正在为MySQL中的数据库规划以下场景 -

我正在尝试通过游戏系统建立一个游戏,比如NBA,

等事件
 Play event[id, play_type_id, play_outcome_id, points] 

  Substitution event[id, player1_in_id, player2_out_id]  

  Foul event[id, foul_type_id, player_id] 

在主play_by_play记分卡中,特定事件应与特定时间相匹配

Play_by_Play[id, match_id, time_id, play_event_id, substitution_event_id, foul_event_id] 

然而,假设在一个特定时刻只发生三个事件中的一个 - 只有一个事件记录中的三个将具有id,而其他事件将为0或NULL。我留下的问题是这个设计的良好标准化还是有更好的方法吗?

2 个答案:

答案 0 :(得分:2)

如果目标是跟踪事件,则将焦点放在单个表中每个事件的一行。

play_typefoul_type混合到一个type中,substitution as another类型`。

考虑拆分"替换"分为两个事件:玩家被移除和玩家被添加。这消除了仅针对此事件存在的额外播放器列。 (但如果你想把它称为单个事件,它会使事情变得复杂。)

可能需要少量NULLable列。

答案 1 :(得分:1)

我认为只有一个答案,而且高度依赖于您如何使用数据。

一种方法是让Play_by_Play表包含对事件的单个引用,从而避免NULL和0的开销。

Play_by_Play[id, match_id, time_id, event_id]

您可以定义通用事件

Event_type [event_type_id, type_name]
Generic_Event[event_id, event_type_id]

并且所有其他事件类型可以是此通用事件类型的1:1扩展名:

Play event[id, event_id, play_type_id, play_outcome_id, points] 
Substitution event[id, event_id, player1_in_id, player2_out_id]  
Foul event[id, event_id, foul_type_id, player_id] 

此设计有利于规范化,并允许快速选择有关事件的信息,无论其类型如何(您的设计需要多次连接)。

但是,聚合信息需要更多的连接(实际上保存事件相关数据的表格),Generic_Event可能会增长,对性能产生潜在影响。

您的方式有利于更快地聚合信息,因为您只能查询Play_by_Play表。例如:在一个时间范围内获得替换次数和犯规次数。

它可能还有更多空间和查询执行效率,因为您使用较少的JOIN并且没有大事件表。

目前还不清楚您的实际数据库引擎是什么(您标记了MySql和SQL Server),但对于SQL Server,有一项功能可以帮助您优化具有大量NULL值的表的空间:sparse columns。< / p>