我有2个数据库表:团队和游戏。
出于这个问题的目的,我们正在处理足球(足球)队和比赛。
每场比赛都有2支球队,通常是主队和客队,但偶尔两队都可以保持中立。
我的问题是我是否应该使用Games表中的2个外键(home_team_id,away_team_id)表示这种数据关系,或者我是否应该使用与games_teams表的多对多关系来链接这两者,在这种情况下我还需要存储球队是主队还是客队,看起来有点矫枉过正。
为了增加混乱,我在KohanaPHP中使用ORM库,这些期望fk被称为team_id或链接表只包含2列。如果您在KohanaPHP中遇到过这个问题的经验,那么请回复,否则任何一般性建议也非常感谢。
答案 0 :(得分:9)
只需使用两列,否则您只需要在joiner表中对其进行限定。这不像是一个沉睡的定时炸弹,突然有一天你会发现你需要真正的多对多。
答案 1 :(得分:6)
2列非常合适。任何游戏都可能只有两个团队的事实通过两列来反映在数据库模式中。通过引入链接表,您可以介绍单个游戏可能拥有2个主队,2个客队,并且您需要进行额外验证以确保此场景永远不会发生的可能性。通过将事物隔离到两列,您的模式本身就可以强制执行数据完整性。
答案 2 :(得分:3)
如果您希望能够在数据库服务器上固定“Xth Normal Form”徽章,那么它应该被视为多对多,否则,我认为您将减少查询开销1您希望通过每个时间加入一些有用数据的表格。
答案 3 :(得分:2)
在规范化方面:是的。只有一对多或多对多被分解为一个或多个一对多关系。
但实际上,如果我要保存像GENDER这样的东西。我真的需要附加多州和日期时间戳吗?
令人惊讶的答案是肯定的 - 但只有当我需要出于商业原因追踪性别变化时 - 出于大多数实际目的,答案是否定的。
我会保留一张有两把钥匙的桌子 - 除非有商业原因要跟踪它。
答案 4 :(得分:1)
取决于你如何抽象它,我会说足球比赛必须有两个队,在这种情况下,在游戏桌上有列不仅更方便,更正确。
我甚至可以想象团队ID是游戏主键的自然组成部分。
答案 5 :(得分:1)
完全认为你不应该有一个单独的表格。程序员更容易,数据库更容易。很高兴考虑ifs,但听起来像你已经拥有。不要觉得规范化始终是一切的方法。
答案 6 :(得分:1)
我尊重对方的答案,说使用两列是最好的选择,但是,你提到你在Kohana使用ORM库。通过在游戏表中使用两列,您将丢失多对多关系的ORM功能。如果您设置了games_teams数据透视表,则可以执行以下操作:
$game = ORM::factory('game', 1); // 1 is the game id
然后你可以循环游戏中的团队:
foreach ($game->teams as $team) {
// do stuff with $team
}