弱实体的数据库建模

时间:2012-05-18 16:13:36

标签: mysql sql database database-design data-modeling

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

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

现在order可以有多个history lines。但是,history line本身不能存在。我听说这被称为弱实体,因此来自orders PK 必须是表orderHistory PK 的一部分。

问题

  1. 这真的是一个正确的弱实体关系吗?还有其他方法来识别它们吗?
  2. 我应该将表格order PK 添加到表格orderHistory并将其设为复合主键吗?
  3. 如果我决定向orderHistory添加新记录,我将如何添加新的复合键? (orderID可从表orders获得,但historyLineID应自动递增。)
  4. 如果我决定将此模型设置为正常的一对多关系,而orderID仅作为外键 添加?这样做的缺点是什么?
  5. 如果所有表格都处于第3范式,那么在设计的后期会忽略弱实体会导致任何问题吗?
  6. 注意

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

2 个答案:

答案 0 :(得分:7)

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

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

您必须问:historyLineID可以是唯一的单独,还是与orderID结合使用?我怀疑后者就是这种情况,这会使它成为一个弱势实体。

  

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

你告诉我们的不是弱实体 - 父母的PK不会迁移到孩子的PK中。

  

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

您基本上有两种选择:

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

    enter image description here

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

    enter image description here

  

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

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

  

如果我决定将其建模为正常的一对多关系,其中orderID被添加为外键,该怎么办?这样做的缺点是什么?

这不是 - 或者。字段可以是FK和(主要或备用)键的一部分,如上所示。

  

如果所有表格都处于第3范式,那么忽略弱实体会导致设计中出现任何问题吗?

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

答案 1 :(得分:0)

  1. 由于依赖,这是一种弱的实体关系,但它本质上是一种犹豫不决的例子。订单可能包含一对多的历史记录行,但每个历史记录行必须具有orderID,对吗?
  2. 这听起来像是一种可选的强制性关系。  所以你的orderId在orderHistory中有“可选”属性...... 2.通过使主键成为orderID和historyLineID的组合,可以部分解决问题 3.您必须在orderID表上执行复制关系。因此,您必须重新加入order.orderID,然后创建新的historyLineID,否则您无法创建尚未存在的内容。 这是应该的方式。对于处理脚本的未来人员,以及可能是您自己,更容易理解这种方式。使用外键创建具有多个historyLineID(子)的orderID(父),因为订单可以有多个订单行,这种方法可能是最好的。

    LINK:enter link description here