我一直搞砸 1NF

发布于 2024-10-31 10:31:17 字数 1135 浏览 1 评论 0原文

对我来说,到目前为止我发现的关于 1NF 最容易理解的描述是“主键是唯一标识每一行的一列(或一组列)”。 ' 在 www.phlonx.com 上 我知道冗余意味着每个键每行的值不应超过 1 个。超过 1 个值将是“冗余”。正确的?

尽管如此,我还是多次搞砸了 1 NF。 我发布了有关我的在线披萨店 http://foo.com 的问题 披萨店 在这里

我对第二范式中的某些内容感到困惑,只是注意到我1 NF 一开始就错了。 现在我想我需要 1NF 中的 3 个键才能唯一标识每一行。 在本例中,我发现 order_id、pizza_id 和 topping_id 可以为我做到这一点。这是 3 列。因为如果你想知道哪个特定的披萨,你需要知道它的 order_id 是什么类型的披萨 (pizza_id) 以及上面有什么配料。如果您知道这一点,您可以查找其余所有内容。 然而,从对上一个问题的回答来看,这似乎是错误的,因为 topping_id 进入了另一个我不理解的表。 以下是列列表:

Order_id
订单_日期
客户_id
客户_姓名
电话
促销
黑名单 Y 或 N
客户_地址
邮政编码
城市
电子邮件
Pizza_id
Pizza_name
尺寸
披萨_价格
金额
Topping_id
Topping_name
Topping_prijs
可用
送货_id
送货_区
Deliveryguy_id
Deliveryguy_name
交付 Y 或 N

编辑:我用粗体标记了第一个串联键的 id。它们只是未标准化的列列表。它们不是 1 张桌子或 3 张桌子或任何东西

For me the most understandable description of going about 1NF so far I found is ‘A primary key is a column (or group of columns) that uniquely identifies each row. ‘ on www.phlonx.com
I understand that redundancy means per key there shouldn’t be more than 1 value to each row. More than 1 value would then be ‘redundant’. Right?

Still I manage to screw up 1 NF a lot of times.
I posted a question for my online pizzashop http://foo.com
pizzashop
here

where I was confused about something in the second normal form only to notice I started off wrong in 1 NF.
Right now I’m thinking that I need 3 keys in 1NF in order to uniquely identify each row.
In this case, I’m finding that order_id, pizza_id, and topping_id will do that for me. So that’s 3 columns. Because if you want to know which particular pizza is which you need to know what order_id it has what type of pizza (pizza_id) and what topping is on there. If you know that, you can look up all the rest.
Yet, from an answer to previous question this seems to be wrong, because topping_id goes to a different table which I don’t understand.
Here’s the list of columns:

Order_id
Order_date
Customer_id
Customer_name
Phone
Promotion
Blacklist Y or N
Customer_address
ZIP_code
City
E_mail
Pizza_id
Pizza_name
Size
Pizza_price
Amount
Topping_id
Topping_name
Topping_prijs
Availabitly
Delivery_id
Delivery_zone
Deliveryguy_id
Deliveryguy_name
Delivery Y or N

Edit: I marked the id's for the first concatenated key in bold. They are only a list of columns, unnormalized. They're not 1 table or 3 tables or anything

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

琉璃繁缕 2024-11-07 10:31:17

使用对象角色建模(例如 NORMA)来捕获有关设计的信息,按按钮,它会输出 SQL。

这比让您在 1NF、2NF 等之间来回更容易。ORM 设计保证采用 5NF。

一些注意事项:

  • 可以拥有复合键
  • 代理键可以概念和逻辑设计之后添加:您已经将它们添加到前面,这是不好的。添加它们是因为 RDBMS 性能,而不是在设计时
  • 阅读有关 1NF 的多个源代码吗?
  • 从简单的英语和一些事实开始。这就是 ORM 对语言化所做的事情。

所以:

  1. 一个顾客有很多披萨(零到 n)
  2. 一个披萨有很多配料(零到 n)
  3. 一个顾客有一个地址
  4. 一个披萨有一个底料
  5. ...

use Object Role Modelling (say with NORMA) to capture your information about the design, press the button and it spits out SQL.

This will be easier than having you going back and forth between 1NF, 2NF etc. An ORM design is guaranteed to be in 5NF.

Some notes:

  • you can have composite keys
  • surrogate keys may be added after both conceptual and logical design: you have added them up front which is bad. They are added because of the RDBMS performance, not at design time
  • have you read several sources on 1NF?
  • start with plain english and some facts. Which is what ORM does with verbalisation.

So:

  1. A Customer has many pizzas (zero to n)
  2. A pizza has many toppings (zero to n)
  3. A customer has an address
  4. A pizza has a base
  5. ...
羅雙樹 2024-11-07 10:31:17

为此,我将使用更多的表,以删除客户、订单、配料和披萨的重复:

表:客户

   Customer_id
    Customer_name
    Customer_name
    Phone
    Promotion
    Blacklist Y or N
    Customer_address
    ZIP_code
    City
    E_mail

表:订单

Order_id
Order_date
Customer_id
Delivery_zone
Deliveryguy_id
Deliveryguy_name
Delivery Y or N

表:Order_Details

Order_ID (FK on Order)
Pizza_ID (FK on Pizza)
Amount

表:披萨

Pizza_id
Pizza_name
Size
Pizza_price

表:浇头

Topping_id
Topping_name
Topping_prijs
Availabitly

表:Pizza_Topping

Pizza_ID
Topping_ID

Pizza_topping 和 Order_details 是所谓的互选表(用于建模两个表之间的 am:n 关系的“辅助”表)。

现在假设我们只有一份披萨和一些配料,而我们的客户 Billy Smith 订购了 2 个 quattro stagione 披萨 - 我们的表格将包含以下内容:

Pizza(Pizza_ID, Pizza_name, Pizza_price)

  1 Quattro stagioni 12€

Topping(Topping_id, topping_name, topping_price)

  1 Mozzarrella 0,50€
  2 Prosciutto 0,70€
  3 Salami 0,50€

Pizza_Topping(Pizza_ID, Topping_ID)

 1 1
 1 3

(此处,quattro stagioni 披萨仅包含马苏里拉奶酪和萨拉米香肠)。

Order(order_ID, Customer_name - 其余省略)

1 Billy Smith

Order_Details(order_id, Pizza_id, amount)

1 1 2  

我已删除交货 ID,因为对我来说,订单和交货之间没有区别 - 或者您支持部分交货吗?

I'd use some more tables for this, to remove duplication for customers, orders, toppings and pizze:

Table: Customer

   Customer_id
    Customer_name
    Customer_name
    Phone
    Promotion
    Blacklist Y or N
    Customer_address
    ZIP_code
    City
    E_mail

Table: Order

Order_id
Order_date
Customer_id
Delivery_zone
Deliveryguy_id
Deliveryguy_name
Delivery Y or N

Table: Order_Details

Order_ID (FK on Order)
Pizza_ID (FK on Pizza)
Amount

Table: Pizza

Pizza_id
Pizza_name
Size
Pizza_price

Table: Topping

Topping_id
Topping_name
Topping_prijs
Availabitly

Table: Pizza_Topping

Pizza_ID
Topping_ID

Pizza_topping and Order_details are so-called interselection tables ("helper" tables for modelling a m:n relationship between two tables).

Now suppose we have just one pizza, some toppings and our customer Billy Smith orders 2 quattro stagione pizze - our tables will contain this content:

Pizza(Pizza_ID, Pizza_name, Pizza_price)

  1 Quattro stagioni 12€

Topping(Topping_id, topping_name, topping_price)

  1 Mozzarrella 0,50€
  2 Prosciutto 0,70€
  3 Salami 0,50€

Pizza_Topping(Pizza_ID, Topping_ID)

 1 1
 1 3

(here, a quattro stagioni pizza contains only Mozzarrella and Salami).

Order(order_ID, Customer_name - rest omitted)

1 Billy Smith

Order_Details(order_id, Pizza_id, amount)

1 1 2  

I've removed delivery ID, since for me, there is no distinction between an Order and a delivery - or do you support partial deliveries?

纸短情长 2024-11-07 10:31:17

在 1NF,来自维基百科,引用日期:

根据Date对1NF的定义,
一个表是 1NF 当且仅当它是
“与某种关系同构”,其中
具体来说,意味着它满足
满足以下五个条件:

  • 行没有从上到下的顺序。
  • 各列没有从左到右的顺序。
  • 没有重复的行。
  • 每个行和列的交集都恰好包含一个
    来自适用域的值(以及
    没有别的)。
  • 所有列都是常规的[即行没有隐藏组件,例如
    行 ID、对象 ID 或隐藏
    时间戳]。

    —Chris Date,“第一范式的真正含义是什么”,第 127–8 页[4]

前两个在任何现代 RDBMS 中都得到保证。

现代 RDBMS 中可能存在重复行 - 但是,前提是您没有主键(或其他唯一约束)。

第四个是最难的(并且取决于模型的语义) - 例如您的字段 Customer_address 可能会破坏 1NF。可能是,因为如果您与自己(以及系统的任何潜在用户)签订合同,您将始终将地址视为一个整体,并且不想分开街道名称、街道号码和/或楼层,您仍然可以索赔1NF 没有被破坏。

破坏客户地址会更合适,但是您需要解决其中的复杂性,并且可能不会带来任何好处(前提是您永远不必查看地址行的亚原子部分) 。

第五个被一些现代 RDBM 打破了,但是真正重要的是你的模型或系统应该依赖于隐藏元素,这通常是正确的 - 即使你的 RDBMS 在内部使用 OID 进行某些操作,除非你开始将它们用于非- 管理、非维护任务,你可以认为它不违反1NF。

On 1NF, from wikipedia, quoting Date:

According to Date's definition of 1NF,
a table is in 1NF if and only if it is
"isomorphic to some relation", which
means, specifically, that it satisfies
the following five conditions:

  • There's no top-to-bottom ordering to the rows.
  • There's no left-to-right ordering to the columns.
  • There are no duplicate rows.
  • Every row-and-column intersection contains exactly one
    value from the applicable domain (and
    nothing else).
  • All columns are regular [i.e. rows have no hidden components such as
    row IDs, object IDs, or hidden
    timestamps].

    —Chris Date, "What First Normal Form Really Means", pp. 127–8[4]

First two are guaranteed in any modern RDBMS.

Duplicate rows are possible in modern RDBMS - however, only if you don't have primary keys (or other unique constraints).

The fourth one is the hardest one (and depends on the semantics of your model) - for example your field Customer_address might be breaking 1NF. Might be, because if you make a contract with yourself (and any potential user of the system) that you will always look at the address as a whole and will not want to separate street name, street number and or floor, you could still claim that 1NF is not broken.

It would be more proper to break the customer address, but there are complexities there with which you would then need to address and which might bring no benefit (provided that you will never have to look a the sub-atomic part of the address line).

The fifth one is broken by some modern RDBMs, however the real importance is that your model nor system should depend on hidden elements, which is normally true - even if your RDBMS uses OIDs internally for certain operations, unless you start to use them for non-administrative, non-maintenance tasks, you can consider it not breaking the 1NF.

恋竹姑娘 2024-11-07 10:31:17

关系数据库的优势在于将信息分离到不同的表中。查看表格的一种有用的方法是首先将那些相对相关的概念识别为实体表。永久(在您的情况下,可能是披萨、顾客、配料、送货员)。然后您考虑它们之间的关系(在您的例子中为 Order, Delivery )。关系表通过指向相关实体的外键将实体表链接在一起:订单有客户、披萨、配料的外键); Delivery 具有 Deliveryguy 和 Order 的外键。而且,是的,关系可以链接关系,而不仅仅是实体。

只有在这样的背景下,你才能实现正常化之类的目标。将一堆属性放入一个单一的表中并不会使您的数据库具有任何有意义的关系。

The strengths of relational databases come from separating information into different tables. One useful way of looking at tables is first to identify as entity tables those concepts which are relatively permanent (in your case, probably Pizza, Customer, Topping, Deliveryguy). Then you think about the relations between them (in your case, Order, Delivery ). The relational tables link together the entity tables by having foreign keys pointing to the relevant entities: an Order has foreign keys to Customer, Pizza, Topping); a Delivery has foreign keys to Deliveryguy and Order. And, yes, relations can link relations, not just entities.

Only in such a context can you achieve anything like normalization. Tossing a bunch of attributes into one singular table does not make your database relational in any meaningful sense.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文