识别和非识别关系之间有什么区别?

Loc*_*yen 773 database database-design data-modeling identifying-relationship

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

Bil*_*win 1028

  • 一个确定的关系是当一个子表行的存在依赖于父表中的一行.这可能会令人困惑,因为现在通常的做法是为子表创建伪代码,但不要将外键设置为子代主键的父部分.在形式上,这样做的"正确"方法是使外键成为孩子主键的一部分.但逻辑关系是,没有父母,孩子就不能存在.

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

    我们可能会将电话号码视为属于某个人,即使它们被建模为单独表格的属性.这是一个强有力的线索,这是一种识别关系(即使我们不在字面上包含person_id在主键中PhoneNumbers).

  • 非识别关系是当父的主键属性不能成为孩子的主键属性.一个很好的例子是查找表,例如Person.state引用主键的外键States.state. Person是一张儿童餐桌States.但是其中的行Person没有通过其state属性标识.即state不是主键的一部分Person.

    非标识关系可以是可选的强制的,这意味着外键列分别允许NULL或不允许NULL.


另请参阅我对仍然困惑关于识别与非识别关系的答案

  • @hobodave:我看到了更大的多列主键.但我明白你的观点.考虑多列主键传达更多信息; 您可以查询特定建筑物中所有床位的"床"表,而无需进行*任何*连接. (21认同)
  • 似乎"正确地"构建识别关系会导致令人讨厌的巨大主键.例如,建筑有地板有房间有床.床的PK将是(bed_id,floor_id,room_id,building_id).看起来很奇怪,我从未在实践中看到这一点,也没有听说它是一种做任何事情的方式.这是PK中的大量冗余数据. (16认同)
  • +1:比尔,"这些天来常见的做法是为子表创建一个伪代码,但不要将外键作为子主键的父部分" - 这是为什么会这样做的链接?谷歌让我失望. (7认同)
  • 我永远不会用它来模拟那个.最佳答案来自下面的"aqsa rao",其中说明了以下内容:"识别关系意​​味着在没有父级的情况下无法唯一地识别子表." 因为你的定义是添加可能会让人困惑的不必要的语义.实体之间的依赖关系不是您创建识别关系或非识别关系的原因. (4认同)
  • @Eugene,是的,我希望这是一个非认同的关系.`user_id`本身应该是主键,`updated_by`不是多列主键的一部分. (2认同)
  • @BillKarwin"人物"和"PhoneNumber"的例子并不是很好.如果将`Person.id`附加到`PhoneNumber`的主键中,那么您将失去数据完整性,因为您可以在`PhoneNumber`中创建一个具有2个人的电话ID的行,例如,对``(123, 45)`和`(123,46)`不会违反任何约束,这不是你想要的. (2认同)
  • 换句话说,您的模型允许您将电话号码附加给 1 个以上的人 (2认同)
  • @BillKarwin 我不是假设。我正在使用模型可以建模的内容。您的“PhoneNumber”表将包含“PK(Person.id, PhoneNumber.id)”。这使得 2 个值的组合来标识一行。同样,你可以有 `(45, 123)` 和 `(46, 123)`。这些值代表 2 行,因为它们是不同的主键。他们还引用了 `Person` 表中的 2 行。现在,您需要确保与这些行的电话号码对应的字段不同。 (2认同)

小智 873

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

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

然而,一本书是由作者撰写的,作者本可以写多本书.但是,这本书需要由作者撰写 - 没有作者就不可能存在.因此,书与作者之间的关系是一种识别关系.

  • 如果这本书是由一位以上的作者写的,会发生什么?它不再是M:N类型的关系,为什么? (12认同)
  • 发生什么事情!!,这不是"识别关系"的有效例子!是的,没有作者就不能写一本书,但书籍表中的作者字段是**不识别**书排! (3认同)
  • 一个不错的解释但我相信扩展这个例子也是有益的.一本书有很多页面.没有页面就不能存在,因此我们可以得出结论,一本书与它所拥有的页数之间的关系也是一种识别关系.但是,页数属性是否会成为本书任何识别方案(关键)的一部分?可能不是.术语"识别关系"通常保留用于涉及*识别*属性的关系 - 关系术语中的*prime*属性. (2认同)
  • 这些真实的例子毫无用处.当您意识到如何在ER中创建表以及数据完整性将如何保持时,您将丢弃这些示例.如果在两个实体之间创建强关系,则强制在实体表中创建主键,并与另一个实体中的PK结合使用.如果你的模型允许你同一本书可以有多个作者,那么你就可以变得坚强.但是如果你的模型只允许你1本作者1本书,你就不能使用强关系来约束这个约束,因为`PK(Book.id,Book.person_id)`. (2认同)
  • 但真正的用法是"没有作者可以预订吗?".现实的答案是肯定的,因为人们会直接寻找这本书.因此在实践中,对于这种情况,它们应该始终是"非识别关系". (2认同)
  • 为了使其技术化,author_id应该在"书籍"中以FK和PK的形式传播.假设一本书没有副本,owner_id也必须传播为FK,而不是PK.您实际上从未真正看到真实世界数据库设计中的第一个识别关系的原因是我们更喜欢通过ISBN识别书籍并将其视为独立的书籍.一本书也可能由一位以上的作者撰写,并且可能有多个副本. (2认同)
  • 您的示例**当且仅当**作者仅写过该书并且书籍表没有任何其他字段来正确识别它(例如其 ISBN)时才有效。所以**这个答案在现实世界的应用程序中无效**。我怎样才能证明这一点?尝试使用其作者字段在亚马逊中查找_Hamlet_。为什么会出现《罗密欧与朱丽叶》的悲剧?也许莎士比亚也写过它? (2认同)

CMS*_*CMS 24

标识关系指定在没有父对象的情况下子对象不能存在

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

如果父级不是必需的,则可以将非标识关系指定为可选,或者通过设置父表基数,在需要父级的情况下将非标识关系指定为必需关系...

  • 这听起来更像是对完全参与关系的描述,而不是对识别关系的描述. (6认同)

Dan*_*yes 24

比尔的答案是正确的,但令人震惊的是,在所有其他答案中,没有人指出最重要的方面.

一遍又一遍地说,如果没有父母,孩子就不能存在并确定关系.(例如user287724).这是事实,但完全忽略了这一点.只要外键足够非空,就可以实现这一点.它不需要是主键的一部分.

所以这是真正的原因:

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

  • 为了实现这一目标,"对于外键足够非空就足够了".它*应该*足够了,但不幸的是,它不是像Entity Framework这样的东西,除非你使用识别关系,否则它不能正常工作,但是实体的"Id"字段会失去它的独特性.只是复合键的一部分. (2认同)

And*_*ite 14

这是一个很好的描述:

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

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
Run Code Online (Sandbox Code Playgroud)

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

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

Child
-----
ID (PK)
ParentID (FK to Parent.ID) -- notice no PK
Name
Run Code Online (Sandbox Code Playgroud)


Acc*_*t م 10

user287724的答案给出了以下书籍和作者关系的例子:

然而,一本书是由作者撰写的,作者可以写出多本书.但这本书需要由作者撰写,如果没有作者,就不能存在.因此,书与作者之间的关系是一种识别关系.

这是一个非常混乱的例子,绝对不是一个有效的例子identifying relationship.

是的,book不能在没有至少一个写author,但author(它的外键)的book不标识bookbooks表!

您可以删除author从(FK)book行,仍然可以通过一些其他的领域(鉴定书行ISBN,ID...等),但书的不是作者!

我认为一个有效的例子是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
Run Code Online (Sandbox Code Playgroud)

在这个例子中,Product_IDprinters_details台被认为是一个FK引用的products.id表,也是一个PKprinters_details表,这是因为一个确定的关系Product_ID在打印机表(FK)是识别子表中的行,我们不能删除在product_id从子表,因为我们无法确定行了,因为我们失去了它的主键

如果你想把它分成两行:

标识关系是子表中的FK被视为子表中的PK(或标识符)同时仍引用父表时的关系

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

import表是具有这些字段的子项(product_id(FK),country_id(FK),导入量,价格,导入的单位,运输方式(空运,海运)) we may use the (product_id , thecountry_id`)以识别每个导入行"如果它们都在同一年"这里两列可以组合子表中的主键(导入)并引用父表.

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

是的,逻辑上一本书没有作者就无法写出,但是一本书可以在没有作者的情况下被识别,实际上它无法与作者一起识别!

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

  • 你是对的,如果你只有表书和作者.那里没有识别关系.但是,如果使用第三个表来表示多对多关系,则第三个表的主键由两个外键组成,引用books表和authors表.该表与书籍和作者都有识别关系.请参阅http://stackoverflow.com/questions/2814469/still-confused-about-identifying-vs-non-identifying-relationships/2814663#2814663中的示例 (5认同)

Ska*_*lot 7

非识别关系

非识别关系意​​味着孩子与父母有关,但可以由孩子自己识别.

PERSON    ACCOUNT
======    =======
pk(id)    pk(id)
name      fk(person_id)
          balance
Run Code Online (Sandbox Code Playgroud)

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

确定关系

识别关系意​​味着父母需要为孩子提供身份.由于父母,孩子完全存在.

这意味着外键也是主键.

ITEM      LANGUAGE    ITEM_LANG
====      ========    =========
pk(id)    pk(id)      pk(fk(item_id))
name      name        pk(fk(lang_id))
                      name
Run Code Online (Sandbox Code Playgroud)

ITEM_LANG和ITEM之间的关系正在确定.在ITEM_LANG和LANGUAGE之间也是如此.

  • PERSON 和 ACCOUNT 如何非识别?没有 PERSON 的 ACCOUNT 怎么存在? (3认同)
  • “PERSON 和 ACCOUNT 为何是非识别性的?” 因为它是这样建模的。无需知道 person_id 即可识别帐户。为什么要这样建模呢?因为一个帐户在其生命周期内可以有不同的人作为其所有者。另一方面,ITEM_LANG 在其生命周期内不能有不同的 ITEM。尽管您可以有不同的组合,但他们的身份与帐户与人员的关系不同。 (2认同)

Dai*_*shi 6

如果您认为删除父项时应该删除子项,那么它是一种识别关系。

如果即使删除了父项也应该保留子项,那么它是一种非识别关系。

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

  • 受训者与培训课程有确定的关系
  • 培训与培训课程具有识别关系
  • 但受训者与文凭有非身份关系

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