【问题标题】:Second normal form question第二范式问题
【发布时间】:2011-07-31 22:20:15
【问题描述】:

当我正常化时,我对自己的思维方式感到不安全。我正在为一家虚构的在线披萨店设计一个数据库。

考虑一个表,其连接键为 order_nr 和 Pizza_article_nr。

我不喜欢披萨配料。我认为从字面上看,他们不依赖披萨,因为从技术上讲,他们可以独立存在。然而实际上,它们总是与披萨有关。那么它们是独立存在的,因此我将在 3NF 中处理它们,还是“toppings”列在 2NF 中失败,因为它确实依赖于实际现实中的比萨饼?

【问题讨论】:

标签: database-design normalization


【解决方案1】:

“但实际上它们总是与披萨有关。”

是吗?

比萨店的业务是,恕我直言,恰好库存中的配料尚未“与比萨饼相关联”,而这正是为了达到目的能够制作比萨饼。

您所说的相当于“引擎始终与汽车相连”。一旦汽车离开生产车间,该陈述可能是正确的,但只要发动机在生产车间的库存/供应中等待获取,它就肯定不是正确的 “连接到汽车”。

【讨论】:

  • 正是我的意思,实际上,浇头在比萨饼上,就像发动机总是在车里一样,但如果你正在考虑正常化,那没关系,我是否正确地跟随你?
【解决方案2】:

您感到困惑的根源在于您在多个地方看到了密钥,并且您认为它一定是冗余的。事实是,在规范化中,您需要忽略密钥中的伪冗余。这不是真正的冗余,而仅仅是信息的重复。重复是有原因的,即表示实体之间的关系。

如果你有一个可用的配料表,即主键是 topping_id,那么一个表会告诉你哪个配料在哪个披萨上是 3NF。如果您没有有浇头查找表,而是将浇头名称放在比萨饼成分表中,那么我想很多人会说您违反了 2NF。如果顶级名称是不是不可变的,他们将是正确的。如果顶部名称碰巧是不可变的,那么有一个论点说顶部名称是隐式顶部表的主键。但是,作为最佳实践,通常最好使用无意义的密钥 - 除非您能想出一个非常好的理由来逐个使用有意义的密钥。因此,请避免在比萨成分表中使用配料名称。

由于您通常一次可以订购多个披萨(我会编写代码并有两个十几岁的儿子,所以我根据经验说话)您的架构可能应该遵循以下思路:

ORDER:
  order_id (PK)
, date_taken
, deliver_to (or FK to a CUSTOMER table if you're being ambitious)

PIZZA:
  pizza_id (PK)
, order_id (FK)
, size

TOPPING:
  topping_id (PK)
, topping_name

PIZZA_COMPOSITION:
, pizza_id (PK, FK)
, topping_id (PK, FK)
, quantity (My kids insist on double cheese)
, coverage (One likes half plain cheese...)

此架构是 3NF,因为出现在多个地方的唯一内容是外键。

【讨论】:

  • 哇。我觉得我需要理解您所说的非常糟糕的内容,以便处理 Web 开发的这一部分。但我没有。第一句话已经让我头疼了。你的意思是我在不止一个地方寻找钥匙?那些地方是什么?
  • 另一个问题(回到 1NF):为什么没有一个包含三个键的表,即 order_id、pizza_id 和 topping_id?因为当我只有一个带有 Pizza_id 的 order_id 时,我知道那个披萨上的配料是什么吗?我不这么认为,因为在同一个订单中,可能会有相同类型的比萨饼配上不同的配料。请注意,我的意思是与额外的浇头相同。
  • 在多个地方的键是指包含关键数据(PK 或 FK)的多个表。具有 3 个键(order、pizza、topping)的表会违反 2NF,因为它包含部分依赖关系。比萨取决于订单,只要一个比萨不能成为两个或多个订单的一部分。浇头也是如此。要标准化,您需要有一张用于比萨饼的桌子,另一张用于在每个比萨饼上添加浇头的桌子以及用于订单的桌子。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2023-03-21
  • 2012-04-24
  • 2020-07-30
  • 1970-01-01
  • 2020-08-29
  • 2015-02-05
  • 2014-02-26
相关资源
最近更新 更多