16

我试图理解一个概念,而不是修复一段不起作用的代码。

我将举一个表单(父表)和表单域(子表)的一般示例。从逻辑上讲,这将是一种识别关系,因为没有表单就不能存在表单域。

form 和 form_field 表

这会让我认为,为了将逻辑关系转换为技术关系,NOT NULLform_field 表中的 form_id 字段的简单就足够了。(见上面截图的左边部分。)

但是,当我使用 MySQL Workbench 添加标识关系时,form_id 不仅NOT NULL是主键,而且还是主键的一部分。(请参见上面屏幕截图的右侧部分。)当我添加一个非识别关系时,NOT NULL仍然如此逻辑地应用它实际上也是一个识别关系。

我想这让我有点困惑,以及直到现在我总是简单地使用 id 字段作为主键的事实。

所以我理解识别与非识别关系的逻辑概念,但我不了解技术部分。

正如这个答案所说,为什么它是“使外键成为孩子主键的一部分的“正确”方法?

这些复合主键有什么好处?

4

2 回答 2

7

从逻辑上讲,这将是一种识别关系,因为没有表单就不能存在表单域。

不,识别关系是关于识别,而不是存在。

任何 X >= 1 的 X:Y 关系保证左侧的存在,无论是否识别。在您的情况下,1:N 关系保证存在form任何给定的form_field. 你可以让它识别或不识别,它仍然可以保证相同。

评论:

  • form_field.form_id您将通过制作密钥的一部分来模拟识别关系。例如form_fieldPK 可能看起来像:{form_id, label},顺便说一句,这对于数据的正确集群非常有益(InnoDB 表始终是集群的)。
  • 只做一个 PK:{id, form_id}是不正确的,因为这个超级密钥不是候选密钥(即它不是最小的——我们可以form_id从中删除并仍然保留唯一性)。
  • 您可以通过使form_field.form_idNULL-able 来模拟 0..1:N 关系(但是您将无法使其也能够识别 - 见下文)。

“识别关系”有两种定义:

  • 严格定义:将父键迁移到子主键1的关系。
  • 松散定义:将父键迁移到子键的关系。

换句话说,松散的定义也允许迁移到备用键(而不仅仅是主键)。

不过,大多数工具2似乎都使用严格的定义,因此如果您将关系标记为标识,这将自动使迁移的属性成为子 PK 的一部分,并且任何 PK 属性都不能为 NULL。


1或者完全由迁移的属性组成,或者是迁移的属性和一些附加属性的组合。

2 ERwin 和 Visio 可以。我还没有使用 MySQL Workbench 进行建模,但您的描述似乎表明它的行为相同。

于 2012-11-08T18:22:55.900 回答
2

识别关系应该是主键包含外键属性的关系。这就是为什么当您将关系指定为标识发布的外键时,它会被视为主键的一部分。

如果在每种情况下都适用相同的键约束和可空性约束,则“识别”关系和非识别关系之间的区别纯粹是信息性的或图解的。该概念类似于指定“主”键并且是指定“主”键的结果。如果一个表有多个候选键,那么所有其他条件都相同,从逻辑角度来看,哪个键被指定为主键并不重要——表的形式、功能和(可能)业务含义是相同的。

但是,在您的示例中,两个表中的键不相同。在第一种情况下,ID 在 form_field 表中是唯一的,而在第二种情况下显然不是。我想这不是你想要的。

于 2012-11-08T18:01:30.970 回答