SQL 第一范式 (1NF) 与序列化
SQL First Normal Form (1NF) vs Serialisation
假设我有一支足球队 table,其中球员姓名与位置相关:
teamId: 1
goalkeeper: 'Marc'
position1: 'John'
position2: 'Erik'
...
但现在我还想要一个代表球员不考虑位置的属性。我将创建一个新属性 teamString
序列化所有按字母顺序排序的玩家(这将确保具有相同玩家的不同 Teams
将具有相同的 teamString
属性):
teamString: Eric-John-Mark[...]
现在我可以过滤 Teams
相同的球员,即使他们踢不同的位置。
这个新属性teamString
会不会违反1NF原则?
提前致谢
您的 teamString
属性将违反 1NF,因为您的 teamString
属性 将包含多个值。并且它会引用同一实体的非关键属性中存在的值(可能是 3NF 违规,但我不确定)。
这里的问题是您将团队中的特定位置视为团队的属性,而不是关系。
我会在 team 和 player 之间建立关系:
team (1, n) - (0, n) player
A team may have one to many players.
A player may play for zero to many teams.
因为两个最大基数都是 n
你会得到一个 多对多 关系,这意味着 join table 两边都有外键(团队id + 玩家id)。在此table您可以为职位类型添加一列。
This means you should get rid of the position columns (goalkeeper
, position1
, ...) in the team table.
位置 table可能看起来像:
team_id
player_id
type
1
12
goal_keeper
1
15
position1
2
12
position_2
然后应用程序可以负责检查球队是否只有有限数量的球员担任特定位置。但是对于建模,您应该坚持在基数中使用的 0、1 和“n”值。
假设我有一支足球队 table,其中球员姓名与位置相关:
teamId: 1
goalkeeper: 'Marc'
position1: 'John'
position2: 'Erik'
...
但现在我还想要一个代表球员不考虑位置的属性。我将创建一个新属性 teamString
序列化所有按字母顺序排序的玩家(这将确保具有相同玩家的不同 Teams
将具有相同的 teamString
属性):
teamString: Eric-John-Mark[...]
现在我可以过滤 Teams
相同的球员,即使他们踢不同的位置。
这个新属性teamString
会不会违反1NF原则?
提前致谢
您的 teamString
属性将违反 1NF,因为您的 teamString
属性 将包含多个值。并且它会引用同一实体的非关键属性中存在的值(可能是 3NF 违规,但我不确定)。
这里的问题是您将团队中的特定位置视为团队的属性,而不是关系。
我会在 team 和 player 之间建立关系:
team (1, n) - (0, n) player
A team may have one to many players. A player may play for zero to many teams.
因为两个最大基数都是 n
你会得到一个 多对多 关系,这意味着 join table 两边都有外键(团队id + 玩家id)。在此table您可以为职位类型添加一列。
This means you should get rid of the position columns (
goalkeeper
,position1
, ...) in the team table.
位置 table可能看起来像:
team_id | player_id | type |
---|---|---|
1 | 12 | goal_keeper |
1 | 15 | position1 |
2 | 12 | position_2 |
然后应用程序可以负责检查球队是否只有有限数量的球员担任特定位置。但是对于建模,您应该坚持在基数中使用的 0、1 和“n”值。