当我正常化时,我对自己的思维方式不安全。我正在为虚构的在线披萨店设计一个数据库。
考虑一个带有连接键的表是order_nr和pizza_article_nr。
我被披萨配料困住了。我认为这是采取的方式,他们不依赖比萨饼,因为从技术上说,他们可以独立存在。但实际上它们总是与披萨相连。那么它们是否存在于自己存在以便我将在3NF中处理它们,或者“浇头”列是否会失败2NF,因为它确实依赖于实际现实中的披萨?
答案 0 :(得分:0)
“但实际上它们总是与披萨相连。”
是吗?
比萨店的业务是,imho,正好有库存的配料尚未“连接到比萨饼”,这正是为了这个目的能够创建比萨饼。
你所说的相当于“发动机总是连接到汽车”。一旦汽车离开生产车间,这种说法可能就是真的,但只要发动机在生产车间的库存/供应中等待得到,它肯定是不为真“连接到汽车”。
答案 1 :(得分:0)
您混淆的根源在于您在多个地方看到了密钥,并且您认为它必须是冗余的。事实是,在规范化中,您需要忽略密钥中的伪冗余。这不是真正的冗余,而只是重复信息。重复是有原因的,即表明实体之间的关系。
如果你有一个可用的浇头表,即主键是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,因为出现在多个位置的唯一内容是外键。