【问题标题】:Primary Keys and Normalization主键和规范化
【发布时间】:2020-06-16 22:13:37
【问题描述】:

我必须将我的数据库标准化为 BCNF,但我对 1NF 有点困惑。

我的主桌是关于视频游戏的,它看起来像这样:

game_id(PK, AI)    title    developer_id(FK)    publisher_id(FK)    genre                   modes                               release_date  
    1              XYZ          3                   5               FPS, Battle Royale      Single-player, multiplayer          2019-02-04

我对“modes”和“genre”列感到困惑,因为有时我有多个值,所以它不是原子的,对吧?这条评论说的是同样的Explain Like I am Five -> How a Primary Key Satisfies First Normal Form,但他下面的评论说的是相反的......

我已经阅读了关于规范化的内容,并在 1NF 中找到了一个表的 this example。回顾我的桌子,我意识到我不能做同样的事情,因为我有一个 'id' 这是一个 PK 所以它不能有重复的值。其他消息来源说,一旦有了 PK,就意味着该表处于 1NF,因为所有行都不同。

我正在考虑创建另外两个表,其中仅存储“模式”(单人游戏/多人游戏/单人游戏、多人游戏)和“流派”。但是,如果游戏只有一个“id”也是 PK,我将如何将“mode_id”作为 FK 插入“游戏”表中?

那我猜它也满足NF2?对于 NF3,我应该再创建两个表来存储游戏模式和游戏类型之间的 n-m 关系...

如果有人想查看我的整个数据库(它又小又简单)并告诉我应该在哪里应用规范化,我会很高兴。谢谢!

【问题讨论】:

  • use text, not images/links, for text--including tables & ERDs。转述或引用其他文本。只提供您需要的东西并将其与您的问题联系起来。仅将图像用于无法表达为文本或增强文本的内容。使用编辑功能插入图像/链接。使您的帖子自成一体。 SO/SE cmets 可以随时删除。 "1NF" has no single meaning. 也不是“关系”。因此,您需要告诉我们您的定义,最好还告诉我们教科书名称和版本。
  • 您的第一个问题是什么? PS 现在你只是要求我们用定制的教程重写你的教科书。请参阅How to Ask,点击谷歌搜索“stackexchange 作业”和投票箭头鼠标悬停文本。按照教科书的理由展示您的工作步骤,并在您遇到困难的第一个地方提出 1 个经过研究的特定非重复问题。引用您依赖的定义和算法。此外,所有步骤都是常见问题解答;但是有很多糟糕和困惑的答案。你必须知道你的“1NF”——在你的链接评论中查看我的帖子! PS“review my design”不是一个有效的 SO 问题。

标签: mysql database database-normalization


【解决方案1】:

您链接的评论是正确的,下面的评论是错误的。

1NF 说每个属性都必须是原子的(这通常是语义上的意思,而不是技术上的意思。从技术上讲,字符串“FPS,Battle Royale”与其他任何字符串一样原子,因为从技术上讲,任何字符串都与其他字符串一样原子。

但 1NF 在语义上意味着:您不应该在单行的单列中存储多个值。

让你的表成为 1NF 最简单的方法就是把它转换成

game_id(PK, AI)    title    developer_id(FK)    publisher_id(FK)    genre          modes                               release_date  
1                  xyz      3                   5                   FPS            Single-player          2019-02-04
1                  xyz      3                   5                   FPS            multiplayer          2019-02-04
1                  xyz      3                   5                   Battle Royale  Single-player          2019-02-04
1                  xyz      3                   5                   Battle Royale  multiplayer          2019-02-04

当然,这只是1NF。完全标准化,应该是这样的:

table GAMES
game_id(PK, AI)    title    developer_id(FK)    publisher_id(FK)    release_date  
1                  xyz      3                   5                   2019-02-04

table GENRES
genre_id(PK)       name
1                  FPS
2                  Battle Royale

table MODES
mode_id(PK)        name
1                  Single-player
2                  multiplayer

table GAME_GENRE
id      game_id      genre_id
1       1            1
2       1            2

table GAME_MODE
id      game_id      mode_id
1       1            1
2       1            2

``




【讨论】:

  • 但是如果是 PK,我怎么能插入具有相同 'game_id' 的另一行?
  • 我是否必须将我的 PK 转换为复合键?我这样做了,我的密钥现在由“game_id”、“genre”和“modes”列组成,我现在可以插入具有相同 id 的多行。这是我首先需要知道的。
  • 是的,完全正确。如果您只保留 1NF,那么您将使用复合键。
  • 好吧,我必须上 BCNF,所以现在我想我必须删除复合键
  • 然后你需要将 1:n 关系移动到不同的表(在我的示例中为 GAME_MODE 和 GAME_GENRE)
猜你喜欢
  • 1970-01-01
  • 2014-03-27
  • 2018-10-05
  • 2012-10-25
  • 2011-08-16
  • 2021-06-13
  • 2011-03-18
  • 2012-01-11
  • 1970-01-01
相关资源
最近更新 更多