识别关系和非识别关系有啥区别?

Posted

技术标签:

【中文标题】识别关系和非识别关系有啥区别?【英文标题】:What's the difference between identifying and non-identifying relationships?识别关系和非识别关系有什么区别? 【发布时间】:2010-10-20 06:16:27 【问题描述】:

我无法完全掌握这些差异。你能描述这两个概念并使用现实世界的例子吗?

【问题讨论】:

好问题,***不会被重新发明:Peter Chen. The Entity Relationship Model, Toward a Unified View of Data, 1976 § 2.3.2: "如果使用关系来识别实体,我们将其称为弱实体关系。如果关系是不用于识别实体,我们称其为常规实体关系”。 OP 问题归结为:What are weak/regular entity relations?. 【参考方案1】:

标识关系是指子表中的行的存在依赖于父表中的行。这可能会让人感到困惑,因为如今为子表创建伪键是一种常见的做法,但将外键设置为子表主键的父部分。形式上,“正确”的做法是让外键成为子主键的一部分。但逻辑关系是,没有父母,孩子就无法存在。

示例:Person 有一个或多个电话号码。如果他们只有一个电话号码,我们可以简单地将其存储在Person 的列中。由于我们要支持多个电话号码,我们创建了第二个表PhoneNumbers,其主键包括引用Person 表的person_id

我们可能会认为电话号码属于某个人,即使它们被建模为单独表格的属性。这是一个强有力的线索,表明这是一种识别关系(即使我们没有在 PhoneNumbers 的主键中真正包含 person_id)。

非标识关系是指父级的主键属性不得成为子级的主键属性。一个很好的例子是查找表,例如Person.state 上的外键引用States.state 的主键。 Person 是相对于 States 的子表。但是Person 中的一行不是由其state 属性标识的。 IE。 state 不是 Person 的主键的一部分。

非标识关系可以是optionalma​​ndatory,这意味着外键列分别允许NULL或不允许NULL。


另见我对Still Confused About Identifying vs. Non-Identifying Relationships的回复

【讨论】:

+1:Bill,“现在的常见做法是为子表创建伪键,但不将外键设置为子表主键的父部分” - 关于原因的任何链接这是? Google 让我失望了。 似乎“正确”构建识别关系会导致令人讨厌的巨大主键。例如楼有楼有房有床。床的 PK 将是 (bed_id, floor_id, room_id, building_id)。奇怪的是,我从未在实践中看到过这种情况,也没有听说过将其作为一种做任何事情的方法。那是PK中的大量冗余数据。 @hobodave:我见过更大的多列主键。但我同意你的观点。考虑多列主键传达更多信息;您可以查询 Beds 表以获取特定建筑物中的所有床位,而无需进行 any 连接。 @Eugene,是的,我希望这是一个非识别关系。 user_id 本身应该是主键,updated_by 不是多列主键的一部分。 我永远不会用它来建模。最佳答案来自下面的“aqsa rao”,它指出以下内容:“标识关系意味着没有父表就无法唯一标识子表。”因为您的定义是添加了不必要的语义,这可能会使人们感到困惑。创建识别或非识别关系的原因不是实体之间的依赖关系。【参考方案2】:

现实世界还有另一种解释:

一本书属于一个所有者,一个所有者可以拥有多本书。但是,这本书也可以在没有所有者的情况下存在,并且它的所有权可以从一个所有者变为另一个所有者。图书与所有者之间的关系是一种非识别关系。

然而,一本书是由一个作者写的,而这个作者可能写了多本书。但是,这本书需要由作者撰写——没有作者,它就无法存在。因此,书与作者之间的关系是一种识别关系。

【讨论】:

一个不错的解释,但我相信稍微扩展示例也很有启发性。一本书有很多页。它不能没有页数而存在,因此我们可以得出结论,一本书与其所拥有的页数之间的关系也是一种识别关系。但是页数属性会成为该书的任何标识方案(键)的一部分吗?可能不是。术语“标识关系”通常保留用于涉及标识属性的关系——关系术语中的属性。 如果这本书的作者超过 1 位会怎样?它不再将关系识别为 M:N 类型,为什么? 这些真实的例子是没用的。当您意识到如何在 ER 中创建表以及如何保持数据完整性时,您就可以丢弃这些示例。如果您在两个实体之间创建强关系,您将强制在实体表中创建一个主键,并结合来自另一个实体的 PK。如果您的模型允许您同一本书可以有多个作者,那么强大就可以了。但是,如果您的模型只允许您 1 个作者 1 本书,那么您就不能使用强关系来限制该约束,因为 PK(Book.id, Book.person_id). 但真正的用法是“没有作者,书还能存在吗?”。答案在现实中是肯定的,因为人们会直接找书。因此在实践中,对于这种情况,它们应该始终是“非识别关系”。 伙计们发生了什么事!!,这不是the Identifying relationship 的有效示例!!!是的,没有作者就不能写一本书,但是,books 表中的作者字段是 NOT IDENTIFYING 书行!!!【参考方案3】:

Bill's answer 是正确的, 但是震惊地看到在所有其他答案中没有人指出最重要的方面。

人们一遍又一遍地说过,在识别关系中,没有父母,孩子就无法生存。 (例如user287724)。这是真的,但完全没有抓住重点。外键为 non-null 就足够了。它不需要是主键的一部分。

这才是真正的原因:

识别关系的目的是外键永远不会改变,因为它是主键的一部分...therefore正在识别!!!

【讨论】:

+1 表示“外键为非空就足够了,可以实现这一点。” 应该足够了,但不幸的是,它不是在涉及到像实体框架这样的东西时,除非你使用识别关系,否则它不能正常工作,但是实体的“Id”字段会丢失它唯一性,因为它只是复合键的一部分。【参考方案4】:

标识关系指定子对象不能 没有父对象而存在

非标识关系指定常规关联 对象之间,1:1 或 1:n 基数。

在没有父级的情况下,可以将非标识关系指定为可选的 在需要父母的情况下,通过设置 父表基数...

【讨论】:

这听起来更像是对完全参与关系的描述,而不是对识别关系的描述。 我不同意上述定义。您可能有一个依赖于其父对象的对象,并且您希望将该对象限制为仅与 1 个父行链接。 HouseWalls。你把房子拆了,你就没有墙了。但一堵墙只属于一所房子。所以做强关系是行不通的:PK(Wall.id, House.id) 将允许您将同一面墙插入到另一个房子的模型中。 拥有House_Wall 表的原因是为了识别房屋内的墙。是识别关系。 House_Wall 表类似于PK(House.id, wall_number), FK(Wall.id)。 wall_number 是房屋中的一个序列,如果没有 House.id,它就不是唯一的。如果你想像PK(Wall.id, House.id) 那样建模并且Wall.id 必须是唯一的,那么将Wall 表中的House.id 作为FK 就足够了。它只是试图为不同的事物建模。【参考方案5】:

这是一个很好的描述:

两个实体之间的关系可分为“识别”或“非识别”。当父实体的主键包含在子实体的主键中时,存在标识关系。另一方面,当父实体的主键包含在子实体中但不作为子实体主键的一部分时,则存在非标识关系。此外,非识别关系可以进一步分类为“强制性”或“非强制性”。当子表中的值不能为空时,存在强制的非标识关系。另一方面,当子表中的值可以为空时,存在非强制性的非标识关系。

http://www.sqlteam.com/article/database-design-and-modeling-fundamentals

这是一个识别关系的简单示例:

Parent
------
ID (PK)
Name

Child
-----
ID (PK)
ParentID (PK, FK to Parent.ID) -- notice PK
Name

这是一个对应的非识别关系:

Parent
------
ID (PK)
Name

Child
-----
ID (PK)
ParentID (FK to Parent.ID) -- notice no PK
Name

【讨论】:

您的答案与 Bill Karwin 给出的答案相冲突,区别在于外键“不是”还是“不得”是子行中主键的一部分。 @Andy White 但是,当它是三列复合主键的一部分时,标识关系中父级的主键是否可以是非强制性的,即 null?【参考方案6】:

user287724's answer 给出了以下书籍和作者关系的例子:

然而,一本书是由一个作者写的,而这个作者可能写了多本书。但是这本书需要作者写,没有作者就不可能存在。因此书和作者之间的关系是一种识别关系。

这是一个非常令人困惑的示例,对于identifying relationship,绝对不是一个有效的示例

是的,如果没有至少一个author,就无法编写book,但是bookauthor(它的外键)是不能识别bookbooks 表中!

您可以从book 行中删除author (FK),并且仍然可以通过其他字段(ISBNID、...等)识别书行,但不能这本书的作者!!

我认为identifying relationship 的一个有效示例是(产品表)和(特定产品详细信息表)1:1 之间的关系

products table
+------+---------------+-------+--------+
|id(PK)|Name           |type   |amount  |
+------+---------------+-------+--------+
|0     |hp-laser-510   |printer|1000    |
+------+---------------+-------+--------+
|1     |viewsonic-10   |screen |900     |
+------+---------------+-------+--------+
|2     |canon-laser-100|printer|200     |
+------+---------------+-------+--------+

printers_details table
+--------------+------------+---------+---------+------+
|Product_ID(FK)|manufacturer|cartridge|color    |papers|
+--------------+------------+---------+---------+------+
|0             |hp          |CE210    |BLACK    |300   |
+--------------+------------+---------+---------+------+
|2             |canon       |MKJ5     |COLOR    |900   |
+--------------+------------+---------+---------+------+
* please note this is not real data

在此示例中,printers_details 表中的 Product_ID 被认为是引用 products.id 表的 FK 和 printers_details 表中的 ALSO PK,这是一种识别关系,因为打印机表中的Product_ID(FK) IS IDENTIFYING 子表中的行,我们无法从子表中删除product_id,因为我们无法再识别该行因为我们丢失了它的主键

如果你想把它放在 2 行中:

识别关系是当 FK 在 子表被视为子表中的 PK(或标识符),而 仍然引用父表

另一个示例可能是当您在某个国家/地区数据库的导入和导出中有 3 个表(进口 - 产品 - 国家)时

import 表是具有这些字段的子表(product_id(FK)、country_id(FK)、进口量、价格、进口单位、运输方式( air, sea) ) we may use the (product_id, thecountry_id`) 以识别进口的每一行“如果它们都在同一年”,这两个列可以在子表(进口)中组成一个主键,并且引用那里的父表。

我很高兴我终于理解了 identifying relationshipnon identifying relationship 的概念,所以请不要告诉我我对所有这些投票都错了完全无效的例子强>

是的,从逻辑上讲,没有作者就不能写一本书,但是没有作者就可以确定一本书,实际上它不能与作者确定!

您可以 100% 从书行中删除作者,但仍然可以识别该书!

【讨论】:

你是对的,如果你只有表格书籍和作者。那里没有识别关系。但是如果你使用第三张表来表示多对多关系,那么第三张表的主键由两个外键组成,分别引用了 books 表和 authors 表。该表与书籍和作者都有识别关系。在***.com/questions/2814469/… 中查看我的示例【参考方案7】:

非识别关系

非识别关系意​​味着孩子与父母相关,但可以单独识别。

PERSON    ACCOUNT
======    =======
pk(id)    pk(id)
name      fk(person_id)
          balance

ACCOUNT 和 PERSON 之间的关系是不可识别的。

识别关系

识别关系意​​味着需要父母向孩子提供身份。孩子只因父母而存在。

这意味着外键也是主键。

ITEM      LANGUAGE    ITEM_LANG
====      ========    =========
pk(id)    pk(id)      pk(fk(item_id))
name      name        pk(fk(lang_id))
                      name

ITEM_LANG 和 ITEM 之间的关系是识别性的。在 ITEM_LANG 和 LANGUAGE 之间也是如此。

【讨论】:

PERSON 和 ACCOUNT 如何无法识别? ACCOUNT 没有 PERSON 怎么可能存在? 为什么上一条评论没有答案? @MrRobot9 "PERSON 和 ACCOUNT 是如何无法识别的?"因为它是这样建模的。可以在不知道 person_id 的情况下识别帐户。为什么要这样建模?因为一个帐户在其生命周期中可以有不同的人作为其所有者。另一方面,ITEM_LANG 在其生命周期内不能有不同的 ITEM。尽管您可以有不同的组合,但它们的身份与帐户与人的关系不同。【参考方案8】:

如果认为在删除父项的同时也要删除子项,那么这是一种识别关系。

如果即使删除了父项也应该保留子项,则它是非标识关系。

例如,我有一个包含受训者、培训、文凭和培训课程的培训数据库:

受训者与培训课程有确定的关系 培训与培训课程具有识别关系 但学员与文凭之间存在非识别性关系

如果删除相关学员、培训或文凭之一,则仅应删除培训课程。

【讨论】:

【参考方案9】:

就像下面链接中很好解释的那样,识别关系有点像 ER 概念模型中与其父级的弱实体类型关系。用于数据建模的 UML 风格 CAD 不使用 ER 符号或概念,关系的种类有:识别、非识别和非特定。

标识关系是父/子关系,其中子实体是一种弱实体(即使在传统的 ER 模型中,它也称为标识关系),其自身属性没有真正的主键,因此无法唯一标识由它自己。在物理模型上,对子表的每次访问都将依赖于(包括语义上)父主键,父主键变成子主键的一部分或全部(也是外键),通常会产生复合键在孩子方面。子项本身最终存在的密钥只是伪密钥或部分密钥,不足以识别该类型实体或实体集的任何实例,没有父项的 PK。

非标识关系是完全独立实体集的普通关系(部分或全部),其实例不依赖于彼此的主键来唯一标识,尽管它们可能需要外键来实现部分或全部关系,但不能作为孩子的主键。孩子有自己的主键。父母同上。两者独立。根据关系的基数,一个的 PK 作为 FK 到另一个(N 侧),如果是部分的,可以为空,如果是全部,则不能为空。但是,在这样的关系中,FK 永远不会是孩子的 PK,就像识别关系一样。

http://docwiki.embarcadero.com/ERStudioDA/XE7/en/Creating_and_Editing_Relationships

【讨论】:

【参考方案10】:

从父级迁移到子级的属性是否有助于识别1子级?

如果:存在标识依赖关系,则关系正在标识,子实体为“弱”。 如果not:标识依赖不存在,关系是非标识的,子实体“强”。

请注意,识别依赖意味着存在依赖,但反之则不然。每个非 NULL FK 都意味着没有父级的子级不能存在,但仅此一项并不能确定关系。

有关这方面的更多信息(以及一些示例),请查看ERwin Methods Guide 的“识别关系”部分。

附:我意识到我参加聚会(非常)迟到了,但我觉得其他答案要么不完全准确(根据存在依赖而不是身份依赖来定义它),要么有点曲折。希望这个答案能提供更多的清晰度......


1 孩子的 FK 是孩子的 PRIMARY KEY 或(非 NULL)UNIQUE 约束的一部分。

【讨论】:

【参考方案11】:

标识关系是指子实体完全依赖于父实体的存在。

示例一个账户表person表和personAccount。person账户表只通过account和person表的存在来标识。

非标识关系是指子表不通过父表的存在来标识。

示例作为 accountType 和 account.accountType 表的表不被标识为 account 表的存在。

【讨论】:

【参考方案12】:

订单处理就是一个很好的例子。来自客户的订单通常具有标识订单的订单号、每个订单出现一次的一些数据(例如订单日期和客户 ID)以及一系列行项目。每个行项目包含一个项目编号,用于标识订单中的行项目、订购的产品、该产品的数量、产品的价格和行项目的金额,可以通过将数量乘以价格。

标识订单项的编号仅在单个订单的上下文中标识它。每个订单中的第一个行项目是项目编号“1”。行项目的完整标识是项目编号及其所属的订单编号。

因此,订单和订单项之间的父子关系是一种识别关系。 ER 建模中一个密切相关的概念称为“子实体”,其中行项目是订单的子实体。通常,子实体与其从属实体具有强制性的子-父标识关系。

在经典数据库设计中,LineItems 表的主键是 (OrderNumber, ItemNumber)。今天的一些设计师会给一个项目一个单独的 ItemID,作为主键,并由 DBMS 自动递增。在这种情况下,我推荐古典设计。

【讨论】:

【参考方案13】:

对Daniel Dinnyes' answer的补充:

在非标识关系中,您不能有两次具有相同值的相同主键列(比如“ID”)。

但是,通过标识关系,您可以让相同的值在“ID”列中显示两次,只要它具有不同的“otherColumn_ID”外键值,因为主key 是两列的组合。

请注意,FK 是否为“非空”并不重要! ;-)

【讨论】:

【参考方案14】:

假设我们有这些表:

user
--------
id
name


comments
------------
comment_id
user_id
text

这两个表之间的关系将识别关系。因为,cmets 只能属于它的所有者,不能属于其他用户。例如。每个用户都有自己的评论,当用户被删除时,该用户的cmet也应该被删除。

【讨论】:

【参考方案15】:

识别关系是两个强实体之间的关系。非识别关系可能并不总是强实体和弱实体之间的关系。可能存在子实体具有主键但其实体的存在可能取决于其父实体的情况。

例如:卖家与书籍之间的关系可能存在,其中卖家可能有自己的主键,但只有在出售书籍时才会创建其实体

参考比尔·卡尔文

【讨论】:

在这里定义“强”和“弱”实体的含义可能会有所帮助。

以上是关于识别关系和非识别关系有啥区别?的主要内容,如果未能解决你的问题,请参考以下文章

多对多关系 (@JoinTable) 中的拥有实体和非拥有实体有啥区别?

主题建模和文档聚类之间有啥关系?

请问OpenCV和OpenGL有啥关系

图像处理和机器学习有啥关系

图像处理、模式识别、计算机图形学之间的相互关系

关系型数据库和非关系型数据库的区别