database - 如果在数据库建模过程中忽略弱实体,会出现什么问题?

标签 database database-design erd

当我进行数据库建模时,我从不使用弱实体,到目前为止一切似乎都很好。我通常通过给每个实体一个主(自动生成)键来忽略整个问题。

但是,我遇到了一些 posts其中提到,如果某些实体的存在完全依赖于其他实体,则它们应该是弱的。

但另一方面,有些人将弱实体称为一个集合,它不具备足够的属性来形成主键。嗯,这意味着我的数据库中的所有实体在我给它们自动递增的 key 之前一开始都很弱。

有人可以概述弱实体的重要性以及不使用它们的后果是什么吗?我们为什么不给每个实体一个主要的自动生成 key 并使其变得强大?

更新:

也许有人可以解释为什么弱实体应该通过父实体的主键 + 标识符来标识,而不是创建代理键并使用外键将其与父实体相关联(在更新和删除时进行级联更改) ?

最佳答案

以一个有多个订单行项目的订单为例。弱实体将是存储在它们自己的表中的单个行项目。它们的主键可以是订单的主键,加上一个简单的整数(例如 1、2、3,这仅在订单内是唯一的。)因此,它们实际上并没有自己的主键作为唯一编号列,它们的键跨越两列,并且只有这样才是唯一的。

如果订单被删除并且当订单被删除时,订单行项目应该被删除——它们单独存在是没有意义的。正是这种联系使它们变得脆弱——删除一个东西应该删除另一个。

如果您为每个订单行项目提供了自己的主键,您仍然需要将它们关联回订单项目,这意味着为订单项目输入一个外键,或者拥有一个交叉引用表。 (您可能还需要知道订单中的行项目编号,这意味着添加一个简单的整数列......此时您已经添加了足够的键来拥有一个没有自动生成的键。)对于设计模式对于拥有的子项目,这些选择中的任何一个都有些矫枉过正。

使用复杂的主键还会加强订单和订单项之间的关系,因为此模式不允许您不能将一个订单项分配给多个订单。

另一个考虑因素是您可以根据订单项目主键对订单和订单行项目进行分片,因为两个表都有该键。 (与常规列相比,基于主键进行分片通常更容易。)


分层包含并不总是您想要的;但是,这是一种经常出现的模式,最好弄清楚它,在这种情况下可以使用复合键。在这里,使用带有订单项的订单项作为子项(即包含),我们不仅说订单项在订单方面是一对多,而且订单项是拥有的并且不独立于订单而存在 —该订单项组成一个订单对象。

与此保持一致,我们明确不会为(所有)订单项(一起作为一个组)管理单独的键空间,而是借用和扩展订单的键空间。不是要求系统为行项目维护一个单独的键空间,而是手动(即不太正式)维护一个外键关系返回到订单,并且还维护一个整数行项目而不是单独(从订单外部引用),我们可以要求系统确保整个组合键的唯一性,其中包括订单中的行项目编号。

当然,您将无法添加与订单无关的订单项,但此外,使用复合子键,您也无法添加与另一个订单重叠的订单项(例如,它不会让您为同一订单添加两个订单项 #3)。

这迫使订单项的生产者和消费者将它们视为包含在订单中和订单的一部分,而不是独立的项目,或者换句话说,通过查看订单来引用订单项,或者,换句话说,通过引用其中一个订单项来获得对“免费”订单的引用。 (并且因为您也将顺序引用作为此类外键的一部分,所以您也可以单独使用复合外键的顺序部分来进行分组或连接。)

关于database - 如果在数据库建模过程中忽略弱实体,会出现什么问题?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14183468/

相关文章:

SQL : select unmatching records from 2 tables

mongodb - 以下和提要的mongodb设计,我应该在哪里嵌入?

sql - 何时使用 NEWID 或 NEWSEQUENTIALID 以及为什么

mysql - 基于多个数据库和表的 ER 图,这些数据库和表从其他表的列值派生名称

mysql - 如何将 MySQL 数据库转换为旧版本?

database - pgbouncer-1.4如何与PostgreSQL -9.0数据库集成

model-view-controller - 现有的营养成分数据库?

sql - SQL 数据库设计中的关系循环

database - ER 图中的 mysql workbench 列图标是什么意思?

database - 如何呈现数据库设计?