5

我的数据库中有 2 个表ordersorderHistory.

 -----------------                    -----------------------
 |  orders       |                    |  orderHistory       |
 -----------------                    -----------------------
 | orderID  (PK) |                    | historyLineID  (PK) |
 | orderDate     |                    | status              |
 | price         |                    | quantity            |
 -----------------                    -----------------------

现在一个order可以有多个history lines. 但是,ahistory line不能单独存在。我听说这被称为弱实体,因此来自的PKorders必须是table的PKorderHistory的一部分。

问题

  1. 这真的是正确的弱实体关系吗?还有其他方法可以识别它们吗?
  2. 我应该将表的PK添加order到表中orderHistory并使其成为复合主键吗?
  3. 如果我决定向 中添加新记录orderHistory,我将如何添加新的复合键?(orderID可从 table 获得orders,但historyLineID应自动递增。)
  4. 如果我决定将其建模为普通的一对多关系,orderID添加为外键怎么办?这样做有什么坏处?
  5. 如果所有表都处于第 3 范式,那么在设计后期完全忽略弱实体会导致任何问题吗?

笔记

orderID&都是historyLineID代理键。提前致谢。

4

2 回答 2

7

一个实体不是弱的,因为它不能独立存在,而是因为它不能独立识别。因此,将“引导”到弱实体的关系称为“识别”关系。在实践中,这意味着父主键被迁移到子 PK 的(通常是正确的)子集(术语“弱实体”通常与主键相关定义,尽管理论上它可以适用于任何键)。

拥有一个不能独立存在但可以独立识别的实体是完全合法的——换句话说,它与非 NULL 存在非识别关系。

你要问:可以historyLineID单独使用,还是结合使用orderID?我怀疑是后者,这将使它成为一个弱实体。

这真的是正确的弱实体关系吗?

您向我们展示的并不是一个弱实体 - 父母的 PK 不会迁移到孩子的 PK 中。

还有其他方法可以识别它们吗?

您基本上有两个选择:

  • orderHistory有一个复合 PK: {orderID, historyLineID},其中orderID是 FK。顺便说一句,这个 PK 可以被认为是“自然的”:

    在此处输入图像描述

  • orderHistory有一个代理 PK: {orderHistoryID},而orderID在 PK 之外。不过,您仍然需要备用密钥{orderID, historyLineID}

    在此处输入图像描述

我应该将表顺序的PK添加到表orderHistory并使其成为复合主键吗?

是的,这是上面描述的第一个选项。除非您自己有孩子关系,否则orderHistory这也是最好的解决方案。如果orderHistory确实有孩子,那么这可能是也可能不是最好的解决方案,这取决于几个因素。

如果我决定将其建模为普通的一对多关系,其中 orderID 被添加为外键怎么办?这样做有什么坏处?

这不是非此即彼。一个字段既可以是 FK,也可以是(主或备用)键的一部分,如上所示。

如果所有表都处于第 3 范式,那么在设计后期完全忽略弱实体会导致任何问题吗?

除非您正确指定密钥,否则您将无法达到 3NF,并且如果不考虑哪些实体可以独立识别,哪些不能独立识别,您将无法做到这一点。

于 2012-05-18T19:29:54.353 回答
0
  1. 由于依赖,它是一种弱实体关系,但本质上是优柔寡断的一个例子。一个订单可能有一对多历史记录行,但每个历史记录行必须有一个 orderID,对吗?

这听起来像是一种可选-强制关系。因此,您的 orderId 在 orderHistory 中具有“可选”属性... 2. 您可以通过将主键设置为 orderID 和 historyLineID 3 的组合来部分解决问题。您必须在 orderID 表上建立一个内卷关系。因此您必须重新加入 order.orderID,然后创建新的 historyLineID,否则您无法在尚不存在的东西上创建。4.这是应该的方式。对于将来编写脚本的人,可能还有您自己,这种方式更容易理解。使用外键创建具有多个historyLineID(子)的orderID(父),因为订单可以有多个订单行,这种方法可能是最好的。

LINK:在此处输入链接描述

于 2012-05-18T16:34:54.090 回答