-1

假设我有一个具有以下属性的表

  • 订单编号
  • 商品编号
  • 项目数量
  • 项目单价
  • 项目付款

其中“项目付款 = 项目单价 x 项目数量”。让我们简化情况,假设每个订单的任意数量只有一个 item id,并且不同的订单可能有相同的 item id。

  1. 什么是主键,“订单 ID”、“订单 ID”和“商品 ID”,或者其他什么?
  2. 如何将其归一化为 3NF?

    这是我正在考虑的解决方案:

    • 包含订单 ID(主键)、商品 ID、商品数量和商品付款的表格

    • 带有项目 id(前一个表的主键和外键)和项目单价的表。

  3. 继续我在第 2 部分中给出的暂定解决方案。在第一个表中,对于每个项目 ID,项目付款与项目数量成正比。如果第一张表的主键是order id,则商品支付依赖于非主键属性的商品数量,违反了3NF无传递性要求。

    我应该将第一个表拆分为:

    • 带有订单 ID(主键)和商品 ID 的表
    • 带有项目 ID(前表的主键和外键)、项目数量和项目付款的表

    或进入:

    • 带有订单 ID(主键)和商品 ID 的表
    • 包含项目单价(原始第二个表的主键和外键)、项目数量和项目付款的表?

谢谢。

4

4 回答 4

2

您可能应该有一个以 OrderID 作为主键的表。这是因为您可能具有对订单具有重要功能依赖关系的属性(例如 order_date、order_status、CustomerID),这些属性不依赖于订单中的一行。

您还应该再次拥有一个 ItemID 是主键的表。同样,它将具有对 ItemID 具有功能依赖关系的属性(例如描述、价格等)

最后你会有第三张桌子。该表将具有 Order 和 Item 的外键。这些键将代表一个候选复合键。您可以使用它或创建一个代理主键 OrderItemID。如果您确实创建了一个代理键,我仍然会确保创建一个唯一键(OrderID、Item)。

     +----------------+         +----------------+
     |  OrderID       |         |    ItemID      |
     +----------------+         +----------------+
     |  CustomerID    |         |   Description  |
     |  OrderDate     |         |   Price        |
     |  Status        |         +----------------+
     |  Payment       |                       |
     +----------------+                       |
            |                                 |
            |                                 |
            |       +---------------------+   |
            |       |   OrderItemID       |   |
            |       +---------------------+   |
            +-------+   OrderID  FK U1    +---+
                    |   ItemID   FK U1    |
                    |   Quantity          |
                    +---------------------+
于 2017-11-07T21:38:31.093 回答
2

让我们不要一开始就谈论ID......

  1. 有订单。订单通常有一个订单号,您可以在发票等上打印该订单号。订单有一个订单日期和一个供应商,当这是关于您向供应商或客户下的订单时,这是关于您的客户向您下的订单。
  2. 有可以订购的物品。项目具有项目编号,例如 GTN(全球贸易编号)。商品有名称和价格,甚至是针对不同日期、不同客户等的价目表。
  3. 一个订单通常可以包含多个商品,例如5件商品A和10件商品B。这些订单位置包含商品、数量和价格。

这可能是表格(主键粗体,唯一列斜体):

  • 客户(客户编号,客户名称
  • 项目(项目编号,项目名称,价格)
  • 订单 ( order_number , order_date, client_number)
  • order_position ( order_number, item_number , 数量, 价格)

您不会存储单个价格和金额以及总价,因为这将是多余的。避免数据库中的冗余,因为这会导致很多问题。

您可以在表中使用技术 ID。您可以将这些表设为主键,但您仍然必须存储上面提到的所有数据,而之前的主键是定义为不可为空且唯一的列或列集,这实际上是与主键相同:

表(主键粗体,唯一列斜体):

  • 客户(client_idclient_numberclient_name
  • 项目 ( item_id , item_number , item_name , 价格)
  • 订单(order_idorder_number,order_date,client_number)
  • order_position ( order_position_id , order_id + item_id , 数量, 价格)
于 2017-11-07T21:43:17.160 回答
1

这看起来像一个订单行。通常,您将拥有订单 ID 和订单行号的主键。item id 应该是 items 表中的外键,它应该有一个价格,但除非你从不提供折扣,否则你的订单行也应该有一个价格。

如果您允许部分付款并希望在该级别进行跟踪,则可以根据订单行支付金额。

于 2017-11-07T21:23:28.237 回答
0

通过您的姓名和常识猜测,您的表格的 3NF 分解是

-- order order_id requests item item_id in quantity item_quantity
order_has_item_in_quantity(order_id, item_id, item_quantity)

-- item item_id has unit price item_unit_price
item_has_unit_price(item_id, item_unit_price)

--     some order requests some item in quantity item_quantity
-- and that item has unit price item_unit_price
-- and item_unit_price * item_quantity = item_payment
unit_price_and_quantity_has_payment(item_unit_price, item_quantity, item_payment)

但是,如果您已经可以访问在 SQL 查询中(通过 operator *)执行的乘法表(这是一个常量),那么您的设计不需要item_payment原始中的列,因此它的分解没有表unit_price_and_quantity_has_payment--是乘法表的一定限制;它是乘法表和前两个表的某个功能。

至于我的猜测,以及相关的 CK(候选键)和理由:规范化使用 FD(功能依赖),而您没有提到它们,因此您似乎对自己在做什么甚至没有基本概念. 所以现在你的问题只是要求一些教科书的一些章节。这太宽泛了——读一些。这里的答案都没有正确解释或参考如何做到这一点——它们对于下一个案例是无用的,对于这个案例来说是不合理的。此外,他们都在猜测您的规格,但应该要求您提供适当的信息。

于 2017-11-08T06:06:24.590 回答